您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關Python爬蟲如何使用Scrapy框架,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
scrapy結構圖:
scrapy組件:
(1)ENGINE:引擎,框架的核心,其它所有組件在其控制下協同工作。
(2)SCHEDULER:調度器,負責對SPIDER提交的下載請求進行調度。
(3)DOWNLOADER:下載器,負責下載頁面(發送HTTP請求/接收HTTP響應)。
(4)SPIDER:爬蟲,負責提取頁面中的數據,并產生對新頁面的下載請求。
(5)MIDDLEWARE:中間件,負責對Request對象和Response對象進行處理。
(6)ITEM PIPELINE:數據管道,負責對爬取到的數據進行處理。
對于用戶來說,Spider是最核心的組件,Scrapy爬蟲開發是圍繞實現Spider展開的。
框架中的數據流:
(1)REQUEST:scrapy中的HTTP請求對象。
(2)RESPONSE:scrapy中的HTTP響應對象。
(3)ITEM:從頁面中爬取的一項數據。
Request和Response是HTTP協議中的術語,即HTTP請求和HTTP響應,Scrapy框架中定義了相應的Request和Response類,這里的Item代表Spider從頁面中爬取的一項數據。
scrapy大致工作流程:
(1)當SPIDER要爬取某URL地址的頁面時,需使用該URL構造一個Request對象,提交給ENGINE。
(2)ENGINE將Request對象傳給SCHEDULER,SCHEDULER對URL進行去重,按某種算法進行排隊,之后的某個時刻SCHEDULER將其出隊,將處理好的Request對象返回給ENGINE。
(3)ENGINE將SCHEDULER處理后的Request對象發送給DOWNLOADER下載頁面。
(4)DOWNLOADER根據MIDDLEWARE的規則,使用Request對象中的URL地址發送一次HTTP請求到網站服務器,之后用服務器返回的HTTP響應構造出一個Response對象,其中包含頁面的HTML文本。DOWNLOADER將結果Resopnse對象傳給ENGINE。
(5)ENGINE將Response對象發送給SPIDER的頁面解析函數(構造Request對象時指定)進行處理,頁面解析函數從頁面中提取數據,封裝成Item后提交給ENGINE。
(6)ENGINE將Item送往ITEMPIPELINES進行處理,最終以某種數據格式寫入文件(csv,json)或者存儲到數據庫中。
整個流程的核心都是圍繞著ENGINE進行的。
Request對象
Request對象用來描述一個HTTP請求,下面是其構造器方法的參數列表。
Request(url, callback=None, method='GET', headers=None, body=None, cookies=None, meta=None, encoding='utf-8', priority=0, dont_filter=False, errback=None, flags=None) # url(必選):請求頁面的url地址,bytes或str類型,如'http://www.baidu.com'。 # callback:頁面解析函數, Callable類型,Request對象請求的頁面下載完成后,由該參數指定的頁面解析函數被調用。如果未傳遞 該參數,默認調用Spider的parse方法。 # method:HTTP請求的方法,默認為'GET'。 # headers:HTTP請求的頭部字典,dict類型,例如{'Accept':'text/html', 'User-Agent':Mozilla/5.0'}。如果其中某項的值為 None,就表示不發送該項HTTP頭部,例如{'Cookie':None},禁止發送Cookie。 # body:HTTP請求的正文,bytes或str類型。 # cookies:Cookie信息字典,dict類型,例如{'currency': 'USD','country': 'UY'}。 # meta:Request的元數據字典,dict類型,用于給框架中其他組件傳遞信息,比如中間件Item Pipeline。其他組件可以使用 Request對象的meta屬性訪問該元數據字典(request.meta),也用于給響應處理函數傳遞信息, # 詳見Response的meta屬性。 # encoding:url和body參數的編碼默認為'utf-8'。如果傳入的url或body參數是str類型,就使用該參數進行編碼。 # priority:請求的優先級默認值為0,優先級高的請求優先下載。 # dont_filter:默認情況下(dont_filter=False),對同一個url地址多次提交下載請求,后面的請求會被去重過濾器過濾 (避免重復下載)。如果將該參數置為True,可以使請求避免被過濾,強制下載。例如,在多次爬取 # 一個內容隨時間而變化的頁面時(每次使用相同的url),可以將該參數置為True。 # errback:請求出現異常或者出現HTTP錯誤時(如404頁面不存在)的回調函數。
雖然參數很多,但除了url參數外,其他都帶有默認值。在構造Request對象時,通常我們只需傳遞一個url參數或再加一個callback參數,其他使用默認值即可。
Response對象:
Response對象用來描述一個HTTP響應,Response只是一個基類,根據響應內容的不同有如下子類:
(1)TextResponse
(2)HtmlResponse
(3)XmlResponse
當一個頁面下載完成時,下載器依據HTTP響應頭部中的Content-Type信息創建某個Response的子類對象。我們通常爬取的網頁,其內容是HTML文本,創建的便是HtmlResponse對象,其中HtmlResponse和XmlResponse是TextResponse的子類。實際上,這3個子類只有細微的差別,這里以HtmlResponse為例進行講解。
下面是HtmlResponse對象的屬性及方法。
url:HTTP響應的url地址,str類型。 status:HTTP響應的狀態碼,int類型,例如200,404。 headers:HTTP響應的頭頭部,類字典類型,可以調用get或getlist方法對其進行訪問,例如:response.headers.get('Content-Type') response.headers.getlist('Set-Cookie') body:HTTP響應正文,bytes類型。 text:文本形式的HTTP響應正文,str類型,它是由response.body使用response.encoding解碼得到的,即reponse.text = response.body.decode(response.encoding) encoding:HTTP響應正文的編碼,它的值可能是從HTTP響應頭部或正文中解析出來的。 request:產生該HTTP響應的Request對象。 meta:即response.request.meta,在構造Request對象時,可將要傳遞給響應處理函數的信息通過meta參數傳入;響應處理函數處理 響應時,通過response.meta將信息取出。 selector:Selector對象用于在Response中提取數據。 xpath(query):使用XPath選擇器在Response中提取數據,實際上它是response.selector.xpath方法的快捷方式。 css(query):使用CSS選擇器在Response中提取數據,實際上它是response.selector.css方法的快捷方式。 urljoin(url):用于構造絕對url。當傳入的url參數是一個相對地址時,根據response.url計算出相應的絕對url。例如: response.url為http://www.example.com/a,url為b/index.html,調用response.urljoin(url)的結果為http://www.example.com /a/b/index.html。
雖然HtmlResponse對象有很多屬性,但最常用的是以下的3個方法:
(1)xpath(query)
(2)css(query)
(3)urljoin(url)
前兩個方法用于提取數據,后一個方法用于構造絕對url。
spied開發流程
實現一個Spider子類的過程很像是完成一系列填空題,Scrapy框架提出以下問題讓用戶在Spider子類中作答:
(1)爬蟲從哪個或哪些頁面開始爬取?
(2)對于一個已下載的頁面,提取其中的哪些數據?
(3)爬取完當前頁面后,接下來爬取哪個或哪些頁面?
實現一個Spider只需要完成下面4個步驟:
(1)繼承scrapy.Spider。
(2)為Spider取名。
(3)設定起始爬取點。
(4)實現頁面解析函數。
scrapy.Spider基類實現了以下內容:
(1)供Scrapy引擎調用的接口,例如用來創建Spider實例的類方法from_crawler。
(2)供用戶使用的實用工具函數,例如可以調用log方法將調試信息輸出到日志。
(3)供用戶訪問的屬性,例如可以通過settings屬性訪問配置文件中的配置。
關于起始URL start_urls:
start_urls通常被實現成一個列表,其中放入所有起始爬取點的url(例子中只有一個起始點)。看到這里,大家可能會想,請求頁面下載不是一定要提交Request對象么?而我們僅定義了url列表,是誰
暗中構造并提交了相應的Request對象呢?
1.我們將起始URL提交給ENGINE。
2.ENGINE調用start_requests方法,我們沒有實現整個方法,所以調用了基類的start_requests方法。
3.通過閱讀Spider基類的源碼可以看到如下內容:
4.基類的start_requests將我們的URL封裝成Request對象。
由此我們知道Request對象是調用基類start_requests方法產生的,因此我們也可以自己定義start_requests方法(覆蓋基類Spider的start_requests方法),直接構造并提交起始爬取點的Request對象。在某些場景下使用這種方式更加靈活,例如有時想為Request添加特定的HTTP請求頭部,或想為Request指定特定的頁面解析函數。
頁面解析函數parse:
頁面解析函數也就是構造Request對象時通過callback參數指定的回調函數(或默認的parse方法)。頁面解析函數是實現Spider中最核心的部分,它需要完成以下兩項工作:
(1)使用選擇器提取頁面中的數據,將數據封裝后(Item或字典)提交給Scrapy引擎。
(2)使用選擇器或LinkExtractor提取頁面中的鏈接,用其構造新的Request對象并提交給Scrapy引擎(下載鏈接頁面)。
一個頁面中可能包含多項數據以及多個鏈接,因此頁面解析函數被要求返回一個可迭代對象(通常被實現成一個生成器函數),每次迭代返回一項數據(Item或字典)或一個Request對象。
內容小結:
(1)了解scrapy的六個組件的功能。
(2)理解scrapy工作流程。
看完上述內容,你們對Python爬蟲如何使用Scrapy框架有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。