現(xiàn)并爬取整個站點)
Scrapling 如何用 SitemapSpider 基于 sitemap 自動發(fā)現(xiàn)并爬取整個站點【免費下載鏈接】Scrapling? An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!項目地址: https://gitcode.com/GitHub_Trending/sc/Scrapling當(dāng)你拿到一個站點的 sitemap.xml想把它列出的所有頁面批量抓下來但又不想為每一類 URL 手寫parse()樣板代碼時Scrapling 的 spider 系統(tǒng)提供了現(xiàn)成的SitemapSpider模板你只需聲明sitemap_urls和一組基于LinkExtractor的規(guī)則它會自動解析 sitemap包括 sitemap 索引把每個 URL 分發(fā)給第一個匹配的回調(diào)處理。本文按「安裝 → 編寫 spider → 運行 → 驗證結(jié)果」的順序走通這條路徑并覆蓋 sitemap 索引、robots.txt 入口和多語言 alternate URL 三個可選分支。前提條件Python 3.10 或更高版本。安裝spider 功能需要 fetchers 依賴Scrapling 的裸裝命令只包含解析引擎不包含 fetchers 和 spiders 所需的依賴此時importscrapling.spiders會拋ModuleNotFoundErrorpip install scrapling使用 spider包括SitemapSpider前必須安裝 fetchers 依賴pip install scrapling[fetchers] scrapling install # 下載瀏覽器及其系統(tǒng)依賴 scrapling install --force # 強(qiáng)制重裝scrapling install會下載所有瀏覽器及其系統(tǒng)依賴和指紋操作依賴如果只走 HTTP 請求這一步也是 fetchers 安裝流程的一部分。安裝完成后from scrapling.spiders import SitemapSpider才能正常導(dǎo)入。SitemapSpider 如何分發(fā) sitemap 里的 URL理解分發(fā)規(guī)則才能解釋為什么某些 URL 沒有出現(xiàn)在結(jié)果里。SitemapSpider繼承自Spider內(nèi)部機(jī)制見 generic-templates.md 與 sitemap.pystart_urls被換成sitemap_urls未設(shè)置sitemap_urls時start_requests()直接拋出RuntimeErrorSitemapSpider needs sitemap_urls to be set.。每個 sitemap URL 先由內(nèi)部的_parse_sitemap回調(diào)解析。遇到sitemapindexsitemap 的 sitemap時自動遞歸下載每個子 sitemap遇到urlset時提取每個url的loc。gzip 壓縮的 sitemap.xml.gz或 gzip content-type會被自動解壓XML 解析失敗只記錄一條 warning如 Failed to parse sitemap XML不會中斷整個爬取。拿到 URL 列表后SitemapSpider按順序用每條規(guī)則的LinkExtractor.matches(url)逐個檢查第一個匹配的規(guī)則獲勝該 URL 以這條規(guī)則的 callback 發(fā)出請求。有規(guī)則但沒有任何規(guī)則匹配該 URL 被丟棄。rules()返回空列表所有 URL 路由到 spider 的parse()方法parse()默認(rèn)實現(xiàn)會拋NotImplementedError所以要么寫規(guī)則要么自己覆寫parse()。LinkExtractor的 URL 過濾參數(shù)來自 generic-templates.md 的參數(shù)表參數(shù)默認(rèn)值說明allow()保留的 URL 模式空表示匹配全部deny()丟棄的 URL 模式永遠(yuǎn)優(yōu)先于allowallow_domains()保留的主機(jī)名子域自動匹配deny_domains()丟棄的主機(jī)名deny_extensionsIGNORED_EXTENSIONS丟棄的文件擴(kuò)展名pdf、zip、圖片、視頻等注意deny_extensions有默認(rèn)值即使allow匹配帶 pdf、zip、圖片等擴(kuò)展名的 sitemap URL 也會被丟棄。編寫并運行一個 SitemapSpider以下代碼結(jié)構(gòu)來自 generic-templates.md 的官方示例。使用前需要替換sitemap_urls換成目標(biāo)站點的真實 sitemap 地址rules()里的allow正則和回調(diào)選擇器按你的站點結(jié)構(gòu)調(diào)整。from scrapling.spiders import SitemapSpider, CrawlRule, LinkExtractor class MySitemap(SitemapSpider): name sm sitemap_urls [https://example.com/sitemap.xml] def rules(self): return [ CrawlRule(LinkExtractor(allowr/posts/), callbackself.parse_post), CrawlRule(LinkExtractor(allowr/products/), callbackself.parse_product), ] async def parse_post(self, response): yield {title: response.css(h1::text).get()} async def parse_product(self, response): yield {sku: response.css(.sku::text).get()} result MySitemap().start()幾個要點回調(diào)必須是 async generatorasync defyield與普通Spider一致。CrawlRule除callback外還支持可選的priority覆蓋和process_request在請求發(fā)出前修改它。start()內(nèi)部處理全部異步機(jī)制爬取過程會記錄到終端結(jié)束后返回CrawlResult對象。驗證爬取結(jié)果start()返回的CrawlResult是判斷是否成功的依據(jù)見 getting-started.mdresult MySitemap().start() # 爬完還是被暫停了 print(fCompleted: {result.completed}) # 訪問抓到的條目 for item in result.items: print(item) # 查看統(tǒng)計 print(fScraped {result.stats.items_scraped} items) print(fMade {result.stats.requests_count} requests) print(fFailed: {result.stats.failed_requests_count}) print(fTook {result.stats.elapsed_seconds:.1f} seconds)條目可以用內(nèi)置方法直接導(dǎo)出父目錄不存在時會自動創(chuàng)建result.items.to_json(sm.json, indentTrue) # JSON result.items.to_jsonl(sm.jsonl) # 每行一個 JSON 對象 result.items.to_csv(sm.csv) # CSV result.items.to_xml(sm.xml) # XML判斷爬取是否正常看三件事result.completed是否為TrueFalse且result.paused為True說明被 CtrlC 暫??芍匦逻\行恢復(fù)stats.failed_requests_count有多少失敗請求stats.items_scraped是否接近你預(yù)期的 sitemap 條目數(shù)。如果發(fā)現(xiàn) sitemap 里的 URL 數(shù)量明顯多于實際請求數(shù)通常是有 URL 沒匹配任何規(guī)則被丟棄了回去檢查rules()的allow正則和deny_extensions默認(rèn)過濾。完整統(tǒng)計清單狀態(tài)碼分布、被 robots.txt 攔截數(shù)、按域的字節(jié)數(shù)等見 advanced.md 的 Results Statistics 一節(jié)??蛇x分支三種 sitemap 入口與過濾只爬部分子 sitemapsitemap 索引當(dāng)根 sitemap 是sitemapindex時SitemapSpider默認(rèn)遞歸進(jìn)入所有子 sitemap。用sitemap_follow指定一個LinkExtractor只進(jìn)入匹配的子 sitemapNone表示進(jìn)入全部class MySitemap(SitemapSpider): name sm sitemap_urls [https://example.com/sitemap.xml] sitemap_follow LinkExtractor(allowr/posts-sitemap-\d\.xml) # 只進(jìn)文章 sitemap用 robots.txt 作為入口把 robots.txt 地址直接放進(jìn)sitemap_urlsSitemapSpider會識別它提取其中所有Sitemap:指令并逐個跟進(jìn)class MySitemap(SitemapSpider): name sm sitemap_urls [https://example.com/robots.txt]如果 robots.txt 里沒有 Sitemap 指令會記錄一條 No Sitemaps found in ... 的 warning爬取不會拿到任何 URL。爬多語言版本頁面設(shè)置sitemap_alternate_links Truexhtml:link relalternate hreflang...中的地址也會被提取并同樣走rules()分發(fā)class MySitemap(SitemapSpider): name sm sitemap_urls [https://example.com/sitemap.xml] sitemap_alternate_links True限制與邊界未設(shè)置sitemap_urls會直接拋RuntimeError不存在其他默認(rèn)入口。有規(guī)則時不匹配任何規(guī)則的 sitemap URL 被靜默丟棄sitemap 里的 PDF、圖片等靜態(tài)資源 URL 受deny_extensions默認(rèn)值影響同樣會被丟棄。sitemap 本身損壞gzip 解壓失敗或 XML 語法錯誤只產(chǎn)生 warning 并跳過該 sitemap需要到爬取日志里找 Failed to decompress sitemap / Failed to parse sitemap XML 來定位是哪個 sitemap 沒被解析。如果站點還有 robots.txt 抓取限制可以像普通 spider 一樣設(shè)置robots_txt_obey True被 Disallow 的請求會計入stats.robots_disallowed_count。大站點爬取被中斷時可通過構(gòu)造參數(shù)crawldir啟用檢查點機(jī)制暫停/恢復(fù)、斷點續(xù)爬用法見 advanced.md 的 Pause Resume 一節(jié)。更多 spider 能力并發(fā)控制concurrent_requests/download_delay、AutoThrottle、流式輸出stream()、生命周期鉤子參考 advanced.md如果不用模板、想在自己的Spider.parse()里直接取鏈接LinkExtractor也可以單獨使用示例同在 generic-templates.md。【免費下載鏈接】Scrapling? An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!項目地址: https://gitcode.com/GitHub_Trending/sc/Scrapling創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考