日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python scrapy框架 简书_python爬虫框架——Scrapy架构原理介绍

發(fā)布時間:2025/3/15 python 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python scrapy框架 简书_python爬虫框架——Scrapy架构原理介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

說起寫爬蟲,大多數(shù)第一時間想到的就是python了。python語法簡潔明了,加上及其豐富好用的庫,用它來寫爬蟲有天然的優(yōu)勢。

之前學python的時候也用requests+lxml寫過幾個爬蟲玩,但是都就爬取一些內容就沒繼續(xù)下去了,都沒做成一個項目,中間python也荒廢了好久。最近要學kafka,就打算爬點數(shù)據(jù)來實踐實踐。于是就學起scrapy來,總的來說,scrapy還是很容易上手的,也比較簡單,花了幾天的時間學習加實踐,也漸漸的掌握了這個爬蟲框架。所以打算寫個博客做個總結,以免之后又太久沒用忘記了。

scrapy架構原理

scrapy架構圖

[圖片上傳失敗...(image-21611e-1532663400039)]

scrapy引擎向spider獲取起始Request集合,也就是spider中定義的start_urls。如果spider重寫了start_requests()方法,那么這個方法返回的Request集合就是起始Request。

scrapy引擎將拿到的Request發(fā)給調度中心開始調度。

scrapy引擎向調度中心請求獲取下一個要爬取的Request。

scrapy引擎拿到Request后,然后將Request發(fā)給下載器。這個過程經過一系列在settings.py中配置的下載中間件,所有在settings.py中配置的下載中間件會依次對Request進行處理。——對應DownloaderMiddleware#process_request()方法

下載器根據(jù)Request拉取響應的內容,比如Request的url是http://www.baidu.com,下載器就會拉取對應的網(wǎng)頁內容下來并封裝成Response對象。

下載器將Response發(fā)送給scrapy引擎。這個過程也會經過一系列在settings.py中配置的下載中間件,這些下載中間件會依次對Response進行處理。——對應DownloaderMiddleware#process_response()方法

scrapy引擎拿到Response后將Response發(fā)給spider,交給對應的spider函數(shù)處理。這里默認方法是parse(),這個回調方法構造Request的時候指定。引擎發(fā)送Response的過程會經過一系列在settings.py中配置的spider中間件,這些spider中間件會依次對Response進行一些處理。——對應SpiderMiddleware#process_spider_input()

spider處理完Response后會返回一個result,這個result是一個包含 Request 或 Item 對象的可迭代對象(iterable)。然后將result發(fā)給scrapy引擎,這個過程也會經過一系列在settings.py中配置的spider中間件,這些spider中間件會依次對這個result進行一些處理。——對應SpiderMiddleware#process_spider_output()

scrapy引擎拿到這個result后,會將其中的Item發(fā)送給Item Pipeline處理,這些item就會被一系列我們在settings.py中配置的pipeline處理。同時,scrapy也會將result中的Request發(fā)給調度中間準備調度。

繼續(xù)重復第2步的步驟,直到所有的Request全部處理完后程序退出。

在scrapy 0.15版本后,spider中間件新增了一個方法,用于處理第一步中spider發(fā)送給引擎的Request,也就是SpiderMiddleware#process_start_requests(start_requests, spider)

scrapy的組件介紹

一、Spider

Spider組件主要用來生成要爬取的url,解析返回的內容,然后生成新的url繼續(xù)交給scrapy去爬取,或者生成item交給pipeline處理。

編寫scrapy爬蟲應用時,我們大多數(shù)精力應該都是放在spider的編寫上面。

通過定義start_urls參數(shù)或者重寫start_requests()方法來給scrapy引擎提供起始的拉取url。

之后,scrapy引擎拿到url后去獲取對應url網(wǎng)頁中的內容后就會回調spider中的parse()方法,我們可以重寫parse()方法來解析scrapy引擎返回回來的內容。

在parse()方法中,我們可以返回一個可迭代的對象,可以理解為是一個list,因為list也是一個可迭代對象,這個list里面可以放Request對象或者Item對象。

scrapy拿到list后,會遍歷整個容器,然后把Request再放進調度等會去獲取內容,對于Item對象,scrapy引擎就把這個item對象發(fā)到pipeline去處理。在pipeline有用戶自己編寫的一套處理邏輯,可以選擇的將item存到文件或者數(shù)據(jù)庫中。

# -*- coding: utf-8 -*-

import scrapy

class TestSpider(scrapy.Spider):

name = "kongtrio"

# 定義爬取的域名,如果返回的url所屬的域名不在這個列表里面,scrapy就不會去爬取內容

allowed_domains = ["bbs.hupu.com"]

# 定義起始的url

start_urls = (

'http://bbs.hupu.com/bxj/',

)

# 如果重寫了這個方法,scrapy引擎取到的起始url就是這個方法返回的內容了

# 這樣start_urls就不會生效了

def start_requests(self):

for i in range(1, 10):

yield scrapy.Request('http://bbs.hupu.com/bxj-' + str(i))

def parse(self, response):

# scrapy拉取到url的內容后,會封裝成Response對象,然后回調這個parse()方法

# 我們可以對這個response進行解析,然后根據(jù)策略返回響應的內容

# scrapy 自帶了xpath的方式解析內容,xpath教程可以看這篇 https://blog.csdn.net/u013332124/article/details/80621638

title_href = response.xpath(".//a[@class='title']/@href").extract_first()

title = response.xpath(".//a[@class='title']/text()").extract_first()

# 返回一個request對象和一個item對象,request對象放的是標題的url,后面scrapy會繼續(xù)讀取這個url然后交給parse繼續(xù)解析

return [scrapy.Request(content_url, self.post_content_parse, dont_filter=True),{"title":title}]

二、pipeline

這也是我們需要關心的組件。前面spider返回的item會經過scrapy引擎的調度發(fā)向pipeline。

pipeline的組件做的事情很簡單,就是拿到item,然后具體的操作用戶自己實現(xiàn)。

class HupuSpiderPipeline(object):

def process_item(self, item, spider):

if not item["title"]:

# 如果這個pipeline拋出DropItem異常,那么這個item就不會傳給后面的pipeline了

raise DropItem("invalid item")

title = item["title"]

print(title)

# return后 會把這個item繼續(xù)傳給后面的pipeline

return item

上面這個pipeline做的事情很簡單,就是從item中獲取title,然后打印出來。

我們可以寫多個pipeline,分別做不同業(yè)務的事情。但是要注意的是,在process_item()方法中,必須將item返回,不然后面的pipeline就不會被調起來處理item了。或者拋出DropItem異常也會中斷item的傳遞。

編寫好pipeline之后還要記得在settings.py里面配置,這樣pipeline才會真正被scrapy引擎知道,并開始工作。

# 后面的數(shù)字表示pipeline的次序

ITEM_PIPELINES = {

'hupu_spider.pipelines.HupuSpiderPipeline': 300,

# 'hupu_spider.pipelines.HupuImgDownloadPipeline': 400,

}

編寫完pipeline和spider,我們其實就基本實現(xiàn)了一個簡單的scrapy爬蟲應用了。挺大一部分場景也只要我們編寫pipeline和spider就可以了。當然,其他的組件也需要了解一下,以面對豐富多樣的需求變動。

三、下載中間件

下載中間件主要是用于在scrapy引擎發(fā)送Request到下載器和下載器返回Response給scrapy引擎的過程中。

scrapy引擎發(fā)送Request到下載器

scrapy引擎發(fā)送Request到下載器的過程中,會經過一個個的下載中間件,這些中間件會對Request進行處理,可以將處理后的Request再發(fā)送給下一個中間件,也可以中斷Request的處理,甚至可以不需要經過下載器就直接生成Response然后返回給scrapy引擎,具體的策略由代碼實現(xiàn)來決定。在所有的中間件都處理過后,下載器拿到Request就會開始下載內容然后返回Response了。

下載器返回Response給scrapy引擎

下載器通過Request拉取到數(shù)據(jù)后,就會封裝成Response返回給scrapy引擎,在這個過程中,也會經過這些下載中間件的處理。下載中間件可以生成Request重新交給scrapy引擎處理,也可以對Response進行一些處理后交給下一個下載中間件,最后抵達scrapy引擎。

下載中間件的定義和使用

我們需要寫一個類來繼承DownloaderMiddleware,并在settings.py中配置編寫好的這個下載中間件。

DOWNLOADER_MIDDLEWARES = {

'myproject.middlewares.CustomDownloaderMiddleware': 543,

'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,

}

后面的數(shù)字表示該下載中間件的順序,數(shù)字越小越接近scrapy引擎

如果要禁用內置的一些下載中間件,可以將數(shù)字設置為None

編寫下載中間件需要關注的幾個方法:

process_request(request, spider): 這個方法接收scrapy傳過來的Request對象,我們可以在這個方法里面對這個Request進行一些處理,然后根據(jù)返回的對象做一些操作:

返回None,通知下一個下載中間件繼續(xù)對這個Request進行處理

返回Response對象,直接生成Response發(fā)給scrapy引擎,這樣Request就不會交給下載器去下載內容了。注意,生成的Response還是會經過一個個下載中間件處理

返回Request對象,直接把新的Request返回給scrapy引擎重新調度,但是后面的下載中間件就不會再執(zhí)行了

如果其raise一個 IgnoreRequest 異常,則安裝的下載中間件的 process_exception() 方法會被調用

process_response(request, response, spider):這個方法接收下載器或者其他下載中間件發(fā)送過來的Response,同時還包括對應的Request對象,并在方法內對response進行一些處理,然后根據(jù)返回的對象類型做一些操作:

如果返回一個Request對象,下載中間件的執(zhí)行就會被停止,并且會把這個Request對象交給scrapy引擎重新調度。

如果返回一個Response對象,就會通知下一個下載中間件繼續(xù)對這個response進行處理

如果其拋出一個 IgnoreRequest 異常,則調用request的errback(Request.errback)

總結

理解了scrapy的整個結構后,下載中間件的功能還是比較好理解的。官方目前也內置了很多實用的下載中間件,所以在大多數(shù)場景下,也不用我們手動去編寫下載中間件。不過復雜的場景還是用的上的,多學一點也沒有壞處。

四、Spider中間件

Spider中間件主要用于scrapy引擎和spider之間的數(shù)據(jù)處理。包括spider發(fā)送Request和Item給scrapy引擎以及scrapy引擎發(fā)送Response給spider。

1. spider發(fā)送Request和Item給scrapy引擎

spider返回Request和Item給scrapy引擎過程中,會經過一個個spider中間件對result進行處理。spider中間件可以拿到spider返回的result和請求返回的response,這個result是Request和Item的迭代對象。spider中間件進行一些處理之后返回一個result。然后下一個spider中間件繼續(xù)拿到result處理。

2.scrapy引擎發(fā)送Response給spider

scrapy引擎發(fā)送Response給spider的過程中,會經過一個個spider中間件對Response進行處理。處理之后spider中間件可以返回None或者拋出一個異常。返回None的話就會繼續(xù)調用下一個spider中間件繼續(xù)處理response,拋出異常的話就不會往下執(zhí)行了。

spider中間件的定義和使用

我們需要寫一個類來繼承SpiderMiddleware,并在settings.py中配置編寫好的這個下載中間件。

SPIDER_MIDDLEWARES = {

'myproject.middlewares.CustomSpiderMiddleware': 543,

'scrapy.contrib.spidermiddleware.offsite.OffsiteMiddleware': None,

}

后面的數(shù)字表示該下載中間件的順序,數(shù)字越小越接近scrapy引擎

如果要禁用內置的一些下載中間件,可以將數(shù)字設置為None

編寫spider中間件需要關注的幾個方法:

process_spider_input(response, spider):

接收scrapy引擎?zhèn)鬟^來的response,用戶可以在方法內處理該response。根據(jù)返回類型的不同會有不同的表現(xiàn)行為:

如果其返回 None ,Scrapy將會繼續(xù)處理該response,調用所有其他的中間件直到spider處理該response

如果其跑出一個異常(exception),Scrapy將不會調用任何其他中間件的 process_spider_input() 方法,并調用request的errback。errback的輸出將會以另一個方向被重新輸入到中間件鏈中,使用 process_spider_output() 方法來處理,當其拋出異常時則帶調用 process_spider_exception() 。

process_spider_output(response, result, spider):

當Spider處理response返回result時,該方法被調用。

必須返回返回包含 Request 或 Item 對象的可迭代對象。

process_spider_exception(response, exception, spider):

當spider或(其他spider中間件的) process_spider_input() 拋出異常時, 該方法被調用

如果其返回 None ,Scrapy將繼續(xù)處理該異常,調用中間件鏈中的其他中間件的 process_spider_exception() 方法,直到所有中間件都被調用,該異常到達引擎(異常將被記錄并被忽略)

如果其返回一個可迭代對象,則中間件鏈的 process_spider_output() 方法被調用, 其他的 process_spider_exception() 將不會被調用

process_start_requests(start_requests, spider):

0.15 新版功能

該方法以spider 啟動的request為參數(shù)被調用,執(zhí)行的過程類似于 process_spider_output() ,只不過其沒有相關聯(lián)的response并且必須返回request(不是item)。

其接受一個可迭代的對象(start_requests 參數(shù))且必須返回另一個包含 Request 對象的可迭代對象

總結

目前scrapy也內置了很多spider中間件,可以滿足大多數(shù)場景。雖然平常時候我們可能不會有寫spider中間件的時候,但是還是有必要了解的。

五、總結

scrapy的架構原理以及相關組件介紹差不多到這里就結束了。熟悉Python的話,scrapy學起來還是很快的。有空寫寫爬蟲也是挺有意思的,大家有空可以學一學。

最后,有對爬蟲或者java技術感興趣的歡迎聯(lián)系我一起交流~本人郵箱在下方

總結

以上是生活随笔為你收集整理的python scrapy框架 简书_python爬虫框架——Scrapy架构原理介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。