
來源:Python爬蟲與數(shù)據(jù)挖掘
作者:霖hero
大家好!我是霖hero。上個月的時候,我寫了一篇關(guān)于IP代理的文章,手把手教你使用XPath爬取免費代理IP,今天在這里分享我的第二篇文章,希望大家可以喜歡。
有一天,我在逛街,突然被一聲靚仔打斷了我的腳步,回頭一看,原來是水果攤阿姨叫我買水果,說我那么靚仔,便宜一點買給我,自戀的我無法拒絕阿姨的一聲聲靚仔,于是買了很多水果回家,家人問我水果多少錢,結(jié)果如何,沒錯,水果買貴了!今天我們使用scrapy框架來爬取北京新發(fā)地價格行情,了解商品價格,家人再也不怕我買貴東西啦。
在爬取之前,我們先來學習一下什么Scrapy框架。
Scrapy是一個基于Twisted的異步處理框架,是純Python實現(xiàn)的爬蟲框架,是提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應用框架,其架構(gòu)清晰,模塊之間的耦合程度低,可擴展性極強,我們只需要少量的代碼就能夠快速抓取數(shù)據(jù)。
首先我們看看經(jīng)典的Scrapy框架架構(gòu)圖,如下圖所示:
學Scrapy框架的絕大部分都看過這個圖,圖中分了很多部分,接下來,我們通過下面的表來簡單地了解各個部分的作用。
名稱 |
作用 |
是否要手寫代碼 |
Engine |
引擎,負責數(shù)據(jù)和信號的在不同模塊間的傳遞。 |
否 |
Scheduler |
調(diào)度器,存放引擎發(fā)過來的requests請求,在引擎再次請求的時候?qū)⒄埱筇峁┙o引擎。 |
否 |
Downloader |
下載器,下載網(wǎng)頁響應的內(nèi)容并將內(nèi)容返回給引擎。 |
否 |
Spiders |
爬蟲,處理引擎?zhèn)鬟^來的網(wǎng)頁內(nèi)容并提取數(shù)據(jù)、url,并返回給引擎。 |
是 |
Item Pipeline |
管道,處理引擎?zhèn)鬟^來的數(shù)據(jù),主要任務是清洗、驗證和存儲數(shù)據(jù)。 |
是 |
Downloader Middlewares |
下載器中間件,位于引擎和下載器之間的橋梁框架,主要是處理引擎與下載器之間的請求及響應,可以自定義下載擴展,如設置代理。 |
一般不用手寫 |
Spider MiddlewaresSpider |
中間件,位于引擎和爬蟲之間的橋梁框架,主要處理向爬蟲輸入的響應和輸出的結(jié)果及新的請求。 |
一般不用手寫 |
在表中,我們可以發(fā)現(xiàn),每部分都要經(jīng)過引擎,上圖中Scrapy Engine部分也是放在正中心,由此可知,Engine引擎是整個框架的核心。
注意:這些模塊部分只有Spiders和Item Pipeline需要我們自己手寫代碼,其他的大部分都不需要。
大致了解了Scrapy框架的各個部分后,接下來我們開始創(chuàng)建一個Scrapy項目,可以使用如下命令:
scrapy startproject <Scrapy項目名>
創(chuàng)建一個scrapy項目名為test1的項目,如下圖所示:
這樣我們就創(chuàng)建好Scrapy項目了,如下圖所示:
其中:
要創(chuàng)建Spider爬蟲,首先我們要進入剛才創(chuàng)建的Scrapy目錄中,再在命令行運行以下命令:
scrapy genspider <爬蟲名字> <允許爬取的域名>
以
http://quotes.toscrape.com
網(wǎng)站為例子,該網(wǎng)站是一個著名作家名言的網(wǎng)站,創(chuàng)建Spider爬蟲如下圖所示:
創(chuàng)建spider爬蟲后,spiders文件夾中多了一個firstspider.py,這個py文件就是我們創(chuàng)建爬蟲,文件內(nèi)容如下所示:
import scrapy class FirstspiderSpider(scrapy.Spider): name = 'firstSpider' allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/'] def parse(self, response): pass
其中:
大致了解了firstspider.py文件內(nèi)容后,我們接下來嘗試在parse()方法中提取響應的數(shù)據(jù),具體代碼如下所示:
xpath_parse = response.xpath('/html/body/div[1]/div[2]/div[1]/div') for xpath in xpath_parse:
item={}
item['text'] = xpath.xpath('./span[1]/text()').extract_first().replace('“','').replace('”','') item['author']=xpath.xpath('./span[2]/small/text()').extract_first() print(item)
這樣我們就成功提取到引擎響應的內(nèi)容數(shù)據(jù)了,接著輸入以下命令來運行spider爬蟲:
scrapy crawl firstSpider
運行結(jié)果如下:
運行后發(fā)現(xiàn)我們結(jié)果里面多了很多l(xiāng)og日志,這時可以通過在settings.py添加以下代碼,就可以屏蔽這些log日志:
LOG_LEVEL="WARNING"
這樣就可以直接輸入我們想要的內(nèi)容,如下圖所示:
有人可能問:那User-Agent在哪里設置?
我們可以在settings.py中設置User-Agent,代碼如下所示:
為了避免拼寫錯誤或者定義字段錯誤,我們可以在items.py文件中定義好字段,在上面提取數(shù)據(jù)中,我們獲取了text、author內(nèi)容,所以我們可以在items.py定義text和author字段,具體代碼如下所示:
import scrapy class Test1Item(scrapy.Item): text= scrapy.Field() author = scrapy.Field()
在items.py文件中,我們只需要使用scrapy.Field()來進行定義即可,scrapy.Field()是一個字典,總的來說我們可以把該類理解為一個字典。
接著在firstspider.py文件中導入我們的items.py,以及修改item={},如下所示:
from test1.items import Test1Item
item=Test1Item()
有人可能會說為什么要多此一舉定義一個字典呢?
當我們在獲取到數(shù)據(jù)的時候,使用不同的item來存放不同的數(shù)據(jù),在把數(shù)據(jù)交給pipeline的時候,可以通過isinstance(item,Test1Item)來判斷數(shù)據(jù)屬于哪個item,進行不同的數(shù)據(jù)(item)處理。
例如我們獲取到京東、淘寶、拼多多的數(shù)據(jù)時,我們可以items.py文件中定義好對應的字段,具體代碼如下:
import scrapy class jingdongItem(scrapy.Item): text= scrapy.Field() author = scrapy.Field() class taobaoItem(scrapy.Item): text= scrapy.Field() author = scrapy.Field() class pddItem(scrapy.Item): text= scrapy.Field() author = scrapy.Field()
定義好字段后,這是我們通過在pipeline.py文件中編寫代碼,對不同的item數(shù)據(jù)進行區(qū)分,具體代碼如下:
from test1.items import jingdongItem class Test1Pipeline: def process_item(self, item, spider): if isinstance(item,jingdongItem):
print(item)
首先我們通過導入我們的items.py,通過isinstance()函數(shù)來就可以成功獲取到對應的item數(shù)據(jù)了。
Item Pipeline為項目管道,當Item生成后,它就會自動被送到Item Pipeline進行處理,我們常用Item Pipeline來做以下操作:
pipelines.py內(nèi)容如下所示:
from itemadapter import ItemAdapter class Test1Pipeline: def process_item(self, item, spider): return item
在process_item()方法中,傳入了兩個參數(shù),一個參數(shù)是item,每次Spider生成的Item都會作為參數(shù)傳遞過來。另一個參數(shù)是spider,就是Spider的示例。
完成pipeline代碼后,需要在setting.py中設置開啟,開啟方式很簡單,只要把setting.py內(nèi)容中的以下代碼的注釋取消即可:
ITEM_PIPELINES = { 'test1.pipelines.Test1Pipeline': 300, }
其中:
注意:
當我們有多個spider爬蟲時,為了滿足不同的spider爬蟲需求,這時可以定義不同的pipeline處理不同的item內(nèi)容;
當一個spider的內(nèi)容可能要做不同的操作時,例如存入不同的數(shù)據(jù)庫中,這時可以定義不同的pipeline處理不同的item操作。
例如當我們有多個spider爬蟲時,可以通過pipeline.py編寫代碼定義多個pipeline,具體代碼如下:
class jingdongPipeline1: def process_item(self, item, spider): if spider.name=="jingdong":
print(item) return item class taobaoPipeline: def process_item(self, item, spider): if spider.name=="taobao":
print(item) return item
這樣我們就可以處理到對應的spider爬蟲傳遞過來的數(shù)據(jù)了。
定義好pipeline后,我們要在settings.py中設置pipeline權(quán)重,也就是那個pipeline先運行,具體代碼如下:
ITEM_PIPELINES = { 'test1.pipelines.jingdongPipeline': 300, 'test1.pipelines.taobaoPipeline': 301, }
在上面我們已經(jīng)提取到想要的數(shù)據(jù),接下來將數(shù)據(jù)傳到pipeline中,傳輸很簡單,我們只需要使用yield,代碼如下:
yield item
沒錯,只要在spider爬蟲中寫入這一行代碼即可,那么為什么要使用yield呢?,我用return不能行嗎?
行,但yield是讓整個函數(shù)變成一個生成器,每次遍歷的時候挨個讀到內(nèi)存中,這樣不會導致內(nèi)存的占用量瞬間變高。
我們成功獲取到了一頁數(shù)據(jù)了,那么問題來了,如何實現(xiàn)翻頁呢,方法有很多種,我們主要介紹兩種。
我們通過在spider爬蟲中,也就是我們創(chuàng)建的firstspider.py中添加以下代碼,具體代碼如下:
def start_requests(self): for i in range(1,3):
url=f'https://quotes.toscrape.com/page/{i}/' yield scrapy.Request(url=url,callback=self.parse)
我們可以通過parse()方法中實現(xiàn)翻頁,具體代碼如下:
for i in range(2,3):
url = f'https://quotes.toscrape.com/page/{i}/' yield scrapy.Request(url=url,callback=self.parse)
大家可以發(fā)現(xiàn),上面兩種翻頁方式都差不多,只是一個在start_requests()方法實現(xiàn),一個在parse()方法實現(xiàn)。
但都要使用scrapy.Request()方法,該方法能構(gòu)建一個requests,同時指定提取數(shù)據(jù)的callback函數(shù)
scrapy.Requeset(url,callback,method='GET',headers,cookies,meta,dont_filter=False)
其中:
我們已經(jīng)獲取到數(shù)據(jù)而且實現(xiàn)了翻頁,接下來是保存數(shù)據(jù)。
保存在文件中
當我們要把數(shù)據(jù)保存成文件的時候,不需要任何額外的代碼,只要執(zhí)行如下代碼即可:
scrapy crawl spider爬蟲名 -o xxx.json #保存為JSON文件 scrapy crawl spider爬蟲名 -o xxx.jl或jsonlines #每個Item輸出一行json scrapy crawl spider爬蟲名 -o xxx.csv #保存為csv文件 scrapy crawl spider爬蟲名 -o xxx.xml #保存為xml文件
想要保存為什么格式的文件,只要修改后綴就可以了,在這里我就不一一例舉了。
保存MongoDB中
當我們要把數(shù)據(jù)保存在MongoDB數(shù)據(jù)庫的時候,就要使用Item Pipeline模塊了,也就是說要在pipeline.py中編寫代碼,具體代碼如下所示:
from pymongo import MongoClient
client=MongoClient()
collection=client["test1"]["firstspider"]
class Test1Pipeline: def process_item(self, item, spider): collection.insert(item) return item
首先我們導入MongoClient模塊并實例化MongoClient,創(chuàng)建一個集合,然后在process_item()方法中使用insert()方法把數(shù)據(jù)插入MongoDB數(shù)據(jù)庫中。
好了,Scrapy知識就講到這里,下一篇文章小編將帶大家爬取北京新發(fā)地價格行情,順便鞏固我們今天學的知識。
大家好,我是霖hero。這篇文章主要給大家分享了Scrapy框架的條條框框,Scrapy是一個基于Twisted的異步處理框架,是純Python實現(xiàn)的爬蟲框架,是提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應用框架,其架構(gòu)清晰,模塊之間的耦合程度低,可擴展性極強。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預期算子的內(nèi)涵、作用與應用解析 動態(tài)隨機一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實戰(zhàn)應用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗與 t 檢驗:差異、適用場景與實踐應用 在數(shù)據(jù)分析與統(tǒng)計學領(lǐng)域,假設檢驗是驗證研究假設、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計劃中 rows 數(shù)量的準確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實踐指南 在 Python 進行 HTTP 網(wǎng)絡請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點數(shù)據(jù)的科學計數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點數(shù)據(jù)時的科學計數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務數(shù)據(jù)分析是企業(yè)解決日常運營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗證業(yè)務邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實戰(zhàn)指南 在業(yè)務系統(tǒng)落地過程中,“業(yè)務邏輯” 是連接 “需求設計” 與 “用戶體驗 ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當下,精準營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實踐到業(yè)務價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導向 統(tǒng)計模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10