Scrapy框架之CrawlSpider爬蟲 實戰 詳解

CrawlSpiderScrapy 框架中一個非常實用的爬蟲基類,它繼承自 Spider
類,主要用于實現基于規則的網頁爬取。相較于普通的 Spider 類,CrawlSpider
可以根據預定義的規則自動跟進頁面中的鏈接,從而實現更高效、更靈活的爬取。

Scrapy 創建CrawlSpider爬蟲

目標網址:http://quotes.toscrape.com/
在這里插入圖片描述
目標:匹配top10標簽里面的所有quote

在這里插入圖片描述
觀察其他的URL鏈接,這些都是干擾,我們只需要匹配top10里面的鏈接,所有需要編寫正則表達式來匹配

1.創建 Scrapy 項目:在命令行輸入scrapy startproject myproject,這里的myproject是項目名。

2.進入項目目錄:輸入cd myproject
3.創建 CrawlSpider:輸入scrapy genspider -t crawl myspider example.commyspider是爬蟲名,example.com是初始爬取的域名。

scrapy genspider -t crawl quotes quotes.toscrape.com
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Ruleclass QuotesSpider(CrawlSpider):name = "quotes"allowed_domains = ["quotes.toscrape.com"]start_urls = ["http://quotes.toscrape.com/"]rules = (Rule(LinkExtractor(allow=r'/tag/[a-z]+/$'), callback='parse_tag', follow=False),)def parse_tag(self, response):tag_url = response.urlprint(f"Extracted tag URL: {tag_url}")
  • rules:是一個元組,包含一個或多個 Rule 對象,每個 Rule 對象定義了一個爬取規則。
  • LinkExtractor(allow=r'/tag/[a-z]+/$'):創建一個 LinkExtractor 對象,使用正則表達式 r'/tag/[a-z]+/$' 來提取符合規則的鏈接。該正則表達式的含義是:匹配含/tag/的鏈接,后面跟著一個或多個小寫字母,最后以 / 結尾的鏈接。
  • callback='parse_tag':當 LinkExtractor 提取到符合規則的鏈接并訪問該鏈接對應的頁面后,會調用 parse_tag 方法來處理該頁面。
  • follow=False:表示不跟進從當前頁面提取的符合規則的鏈接。也就是說,爬蟲只會處理當前頁面中符合規則的鏈接,不會繼續深入這些鏈接對應的頁面去提取更多鏈接。(會自動訪問符合規則的鏈接)
    在這里插入圖片描述
    可以看到爬取的就是top10的

相對 URL 和絕對 URL 的差異: Scrapy 的 LinkExtractor 在處理鏈接時,處理的是絕對 URL 而非 HTML 中的相對 URL。要是你的正則表達式是基于相對 URL 來寫的,就可能會匹配失敗。比如,HTML 里的相對 URL 是/tag/inspirational/,但 Scrapy 處理時會把它變成絕對 URL http://quotes.toscrape.com/tag/inspirational/
因此 r'^/tag/[a-z]+/$' 就無法匹配,因為絕對 URL 是以 http:// 開頭的,并非 /tag/
或者改為這樣也是可以的 r'^http://quotes.toscrape.com/tag/[a-z]+/$'

接下來我們繼續跟進,將follow=True。進入這些標簽頁面進一步爬取詳情內容

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Ruleclass QuotesSpider(CrawlSpider):name = "quotes"allowed_domains = ["quotes.toscrape.com"]start_urls = ["http://quotes.toscrape.com/"]rules = (Rule(LinkExtractor(allow=r'/tag/[a-z]+/$'), callback='parse_tag', follow=True),)def parse_tag(self, response):# 打印當前頁面的URLtag_url = response.urlprint(f"Extracted tag URL: {tag_url}")# 提取名言和作者quotes = response.css('div.quote')for quote in quotes:text = quote.css('span.text::text').get()author = quote.css('small.author::text').get()print(f"Quote: {text}, Author: {author}")

在這里插入圖片描述

翻頁邏輯

有的標簽類別不止一頁數據,例如

http://quotes.toscrape.com/tag/love/page/2/

在這里插入圖片描述
可以看到我們只需要匹配next里面鏈接,其他的為干擾。我們可以使用更精確的 CSS 選擇器來配合 LinkExtractor

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Ruleclass QuotesSpider(CrawlSpider):name = "quotes"allowed_domains = ["quotes.toscrape.com"]start_urls = ["http://quotes.toscrape.com/"]rules = (# 規則1:提取所有標簽鏈接Rule(LinkExtractor(allow=r'/tag/[a-z]+/$'), callback='parse_tag', follow=True),# 規則2:使用CSS選擇器提取<li>標簽下的分頁鏈接Rule(LinkExtractor(restrict_css='li.next a'), callback='parse_tag', follow=True),)def parse_tag(self, response):# 打印當前頁面的URLtag_url = response.urlprint(f"Extracted tag URL: {tag_url}")# 提取名言和作者quotes = response.css('div.quote')for quote in quotes:text = quote.css('span.text::text').get()author = quote.css('small.author::text').get()print(f"Quote: {text}, Author: {author}")

如果 Rule(LinkExtractor(restrict_css=‘li.next a’), callback=‘parse_tag’, follow=False)
那么爬蟲只會處理當前頁面中提取到的分頁鏈接對應的頁面,而不會進一步去跟進這些頁面中的其他分頁鏈接,所以只能獲取到第二頁的數據,無法獲取到第二頁之后的頁面數據。

還可以使用 XPath 提取

    rules = (# 規則1:提取所有標簽鏈接Rule(LinkExtractor(allow=r'/tag/[a-z]+/$'), callback='parse_tag', follow=True),# 規則2:使用CSS選擇器提取<li>標簽下的分頁鏈接Rule(LinkExtractor(restrict_css='li.next a'), callback='parse_tag', follow=True),# 規則3:使用XPath提取<li>標簽下的分頁鏈接Rule(LinkExtractor(restrict_xpaths='//li[@class="next"]/a'), callback='parse_tag', follow=True),)

Scrapy 內部有一個鏈接去重機制,默認使用 scrapy.dupefilters.RFPDupeFilter 來過濾重復的請求。當 LinkExtractor 提取到鏈接后,Scrapy 會先檢查這個鏈接是否已經在請求隊列中或者已經被處理過,如果是,就不會再次發起請求。

規則 2 和規則 3 提取的是相同的,由于 Scrapy 的去重機制,相同的鏈接只會被請求和處理一次,所以不會因為規則 2 和規則 3 提取到相同的鏈接而導致 parse_tag 方法被重復調用并打印兩次數據。

雖然 Scrapy 會對鏈接進行去重,但如果你的 parse_tag 方法內部存在一些邏輯,可能會導致數據重復處理。例如,如果你在 parse_tag 方法中對數據進行了一些存儲操作,并且沒有進行去重處理,那么可能會出現數據重復存儲的情況

LinkExtractor allow參數

  • 字符串列表allow=['/tag/love/', '/tag/humor/']LinkExtractor 會提取包含 /tag/love/ 或者 /tag/humor/ 的鏈接

  • 編譯好的正則表達式對象

    tag_pattern = re.compile(r'/tag/[a-z]+/$')
    rules = (Rule(LinkExtractor(allow=tag_pattern), callback='parse_item', follow=True),
    )
    
  • 空列表或空字符串:如果你傳入一個空列表 [] 或者空字符串 ''LinkExtractor 會提取頁面中的所有鏈接。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904280.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904280.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904280.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Glide 如何加載遠程 Base64 圖片

最近有個需求&#xff0c;后端給出的圖片地址并不是正常的 URL&#xff0c;而且需要一個接口去請求&#xff0c;但是返回的是 base64 數據流。這里不關心為啥要這么多&#xff0c;原因有很多&#xff0c;可能是系統的問題&#xff0c;也可能是能力問題。當然作為我們 Android 程…

004-nlohmann/json 快速認識-C++開源庫108杰

了解 nlohmann/json 的特點&#xff1b;理解編程中 “數據戰場”劃分的概念&#xff1b;迅速上手多種方式構建一個JSON對象&#xff1b; 1 特點與安裝 nlohmann/json 是一個在 github 長期霸占 “JSON” 熱搜版第1的CJSON處理庫。它的最大優點是與 C 標準庫的容器數據&#xf…

#基礎Machine Learning 算法(上)

機器學習算法的分類 機器學習算法大致可以分為三類&#xff1a; 監督學習算法 (Supervised Algorithms&#xff09;:在監督學習訓練過程中&#xff0c;可以由訓練數據集學到或建立一個模式&#xff08;函數 / learning model&#xff09;&#xff0c;并依此模式推測新的實例。…

正弦波、方波、三角波和鋸齒波信號發生器——Multisim電路仿真

目錄 Multisim使用教程說明鏈接 一、正弦波信號發生電路 1.1正弦波發生電路 電路組成 工作原理 振蕩頻率 1.2 正弦波發生電路仿真分析 工程文件鏈接 二、方波信號發生電路 2.1 方波發生電路可調頻率 工作原理 詳細過程 2.2 方波發生電路可調頻率/可調占空比 調節占空比 方波產生…

【AND-OR-~OR鎖存器設計】2022-8-31

緣由鎖存器11111111111-硬件開發-CSDN問答 重置1&#xff0c;不論輸入什么&#xff0c;輸出都為0&#xff1b; 重置0&#xff0c;輸入1就鎖住1 此時輸入再次變為0&#xff0c;輸出不變&#xff0c;為鎖住。

力扣-字符串-468 檢查ip

思路 考察字符串的使用&#xff0c;還有對所有邊界條件的檢查 spilt&#xff08;“\.”&#xff09;&#xff0c;toCharArray&#xff0c;Integer.parseInt() 代碼 class Solution {boolean checkIpv4Segment(String str){if(str.length() 0 || str.length() > 4) retur…

BC8 十六進制轉十進制

題目&#xff1a;BC8 十六進制轉十進制 描述 BoBo寫了一個十六進制整數ABCDEF&#xff0c;他問KiKi對應的十進制整數是多少。 輸入描述&#xff1a; 無 輸出描述&#xff1a; 十六進制整數ABCDEF對應的十進制整數&#xff0c;所占域寬為15。 備注&#xff1a; printf可以使用…

ARM子程序和棧

微處理器中的棧由棧指針指向存儲器中的棧頂來實現&#xff0c;當數據項入棧時&#xff0c;棧 指針向上移動&#xff0c;當數據項出棧時&#xff0c;棧指針向下移動。 實現棧時需要做出兩個決定&#xff1a;一是當數據項進棧時是向低位地址方向向上生 長&#xff08;圖a和圖b&a…

jwt身份驗證和基本的利用方式

前言 &#xff1a; 什么是jwt&#xff08;json web token&#xff09;&#xff1f; 看看英文單詞的意思就是 json形式的token 他的基本的特征 &#xff1a; 類似于這樣的 他有2個點 分割 解碼的時候會有三個部分 頭部 payload 對稱密鑰 這個就是對稱加密 頭部&am…

n8n工作流自動化平臺的實操:利用本地嵌入模型,完成文件內容的向量化及入庫

1.成果展示 1.1n8n的工作流 牽涉節點&#xff1a;FTP、Code、Milvus Vector Store、Embeddings OpenAI、Default Data Loader、Recursive Character Text Splitter 12.向量庫的結果 2.實操過程 2.1發布本地嵌入模型服務 將bge-m3嵌入模型&#xff0c;發布成滿足open api接口…

MATLAB人工大猩猩部隊GTO優化CNN-LSTM多變量時間序列預測

本博客來源于CSDN機器魚&#xff0c;未同意任何人轉載。 更多內容&#xff0c;歡迎點擊本專欄目錄&#xff0c;查看更多內容。 目錄 0 引言 1 數據準備 2 CNN-LSTM模型搭建 3 GTO超參數優化 3.1 GTO函數極值尋優 3.2 GTO優化CNN-LSTM超參數 3.3 主程序 4 結語 0 引言…

git項目遷移,包括所有的提交記錄和分支 gitlab遷移到gitblit

之前git都是全新項目上傳&#xff0c;沒有遷移過&#xff0c;因為遷移的話要考慮已有項目上的分支都要遷移過去&#xff0c;提交記錄能遷移就好&#xff1b;分支如果按照全新項目上傳的方式需要新git手動創建好老git已有分支&#xff0c;在手動一個一個克隆老項目分支代碼依次提…

Photo-SLAM論文理解、環境搭建、代碼理解與實測效果

前言&#xff1a;第一個解耦式Photo-SLAM&#xff0c;亮點和效果。 參考&#xff1a;https://zhuanlan.zhihu.com/p/715311759 全網最細PhotoSLAM的conda環境配置教程&#xff0c;拒絕環境污染&#xff01;&#xff01;-CSDN博客 1. 環境搭建 硬件&#xff1a;RTX 4090D wi…

如何使用VSCode編寫C、C++和Python程序

一、首先準備好前期工作。如下載安裝Python、VSCode、一些插件等。寫代碼之前需要先創建文件夾和文件。 二、將不同語言寫的代碼放在不同的文件夾中&#xff0c;注意命名時不要使用中文。 三、打開VSCode&#xff0c;點擊“文件”->“打開文件夾”->“daimalainxi”->…

基于不確定性感知學習的單圖像自監督3D人體網格重建 (論文筆記與思考)

文章目錄 論文解決的問題提出的算法以及啟發點 論文解決的問題 首先這是 Self-Supervised 3D Human mesh recovery from a single image with uncertainty-aware learning &#xff08;AAAI 2024&#xff09;的論文筆記。該文中主要提出了一個自監督的framework用于人體的姿態…

Leetcode刷題記錄33——二叉樹的最小深度

題源&#xff1a;https://leetcode.cn/problems/minimum-depth-of-binary-tree/description/ 題目描述&#xff1a; 思路一&#xff1a; 使用 DFS 遞歸遍歷的解法&#xff0c;每當遍歷到一條樹枝的葉子節點&#xff0c;就會更新最小深度&#xff0c;當遍歷完整棵樹后&#x…

有效的括號(20)

20. 有效的括號 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:bool isValid(string s) {unordered_map<char, char> m {{), (}, {],[}, {}, {}};stack<char> stk;for (int i 0; i < s.size(); i) {if (s[i] ( || s[i…

電子郵件相關協議介紹

0 Preface/Foreword 1 協議介紹 電子郵件包含的主要協議&#xff1a; SMTPPOPIMAP 1.1 SMPT SMPT: Simple Mail Transfer Protocol&#xff0c;電子郵件傳輸的標準協議&#xff0c;負責將郵件從發送方傳輸到接收方郵件服務器。 1.2 POP POP&#xff1a; Post Office Protoc…

Linux壓縮和解壓類

一、gzip/gunzip 壓縮 1、基本語法 gzip 文件 &#xff08;功能描述&#xff1a;壓縮文件&#xff0c;只能將文件壓縮為*.gz文件&#xff09; gunzip 文件.gz &#xff08;功能描述&#xff1a;解壓縮文件命令&#xff09; 2、經驗技巧 &#xff08;1&#…

力扣hot100 (除自身以外數組的乘積)

238. 除自身以外數組的乘積 中等 給你一個整數數組 nums&#xff0c;返回 數組 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數據 保證 數組 nums之中任意元素的全部前綴元素和后綴的乘積都在 32 位 整數范圍內。 請 不要使用除…