Scrapy 框架介紹
Scrapy是用純Python實(shí)現(xiàn)一個為了爬取網(wǎng)站數(shù)據(jù)、提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架,用途非常廣泛。
Scrapy框架:用戶只需要定制開發(fā)幾個模塊就可以輕松的實(shí)現(xiàn)一個爬蟲,用來抓取網(wǎng)頁內(nèi)容以及各種圖片,非常之方便。
Scrapy 使用了Twisted(其主要對手是Tornado)多線程異步網(wǎng)絡(luò)框架來處理網(wǎng)絡(luò)通訊,可以加快我們的下載速度,不用自己去實(shí)現(xiàn)異步框架,并且包含了各種中間件接口,可以靈活的完成各種需求。
Scrapy架構(gòu)圖
Scrapy主要包括了以下組件:
? ? ScrapyEngine(引擎):
負(fù)責(zé)Spider、ItemPipeline、Downloader、Scheduler中間的通訊,信號、數(shù)據(jù)傳遞等。
?
? ? Scheduler(調(diào)度器):
它負(fù)責(zé)接受`引擎`發(fā)送過來的Request請求,并按照一定的方式進(jìn)行整理排列,入隊,當(dāng)`引擎`需要時,交還給`引擎`。
?
? ? Downloader(下載器):
? ? 負(fù)責(zé)下載`ScrapyEngine(引擎)`發(fā)送的所有Requests請求,并將其獲取到的Responses交還給`ScrapyEngine(引擎)`,由`引擎`交給`Spider`來處理,
?
? ? Spider(爬蟲):
? ? 它負(fù)責(zé)處理所有Responses,從中分析提取數(shù)據(jù),獲取Item字段需要的數(shù)據(jù),并將需要跟進(jìn)的URL提交給`引擎`,再次進(jìn)入`Scheduler(調(diào)度器)`,
?
? ? ItemPipeline(管道):
? ? 它負(fù)責(zé)處理`Spider`中獲取到的Item,并進(jìn)行后期處理(詳細(xì)分析、過濾、存儲等)的地方.
?
? ? DownloaderMiddlewares(下載中間件):
? ? ? ? 你可以當(dāng)作是一個可以自定義擴(kuò)展下載功能的組件。
?
? ? SpiderMiddlewares(Spider中間件):
? ? 你可以理解為是一個可以自定擴(kuò)展和操作`引擎`和`Spider`中間`通信`的功能組件(比如進(jìn)入`Spider`的Responses和從`Spider`出去的Requests)
安裝Scrapy
Scrapy的安裝介紹
? ? Scrapy框架官方網(wǎng)址:http://doc.scrapy.org/en/latest
? ? Scrapy中文維護(hù)站點(diǎn):http://scrapy-chs.readthedocs.io/zh_CN/latest/index.html
安裝方式:
pipinstallscrapy-ihttps://pypi.douban.com/simple
'''
如果安裝出現(xiàn)錯誤,可以按照下面的順序先安裝依賴包:
? ? 1、安裝wheel
? ? ? ? pip install wheel
?? 2、安裝lxml
? ? ? ? pip install lxml
?? 3、安裝pyopenssl
? ? ? ? pip install pyopenssl
?? 4、安裝Twisted
? ? ? ? 需要我們自己下載Twisted,然后安裝。這里有Python的各種依賴包。選擇適合自己Python以及系統(tǒng)的Twisted版本:https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
? ? ? ? # 3.6版本(cp后是python版本)
? ? ? ? pip install Twisted-18.9.0-cp36-cp36m-win_amd64.whl
?? 5、安裝pywin32
? ? ? ? pip install pywin32
?? 6、安裝scrapy
? ? ?? pip install scrapy
安裝后,只要在命令終端輸入scrapy來檢測是否安裝成功
'''
使用Scrapy
使用爬蟲可以遵循以下步驟:
創(chuàng)建一個Scrapy項(xiàng)目
定義提取的Item
編寫爬取網(wǎng)站的 spider 并提取 Item
編寫 Item Pipeline 來存儲提取到的Item(即數(shù)據(jù))
1. 新建項(xiàng)目(scrapy startproject)
創(chuàng)建一個新的Scrapy項(xiàng)目來爬取 https://www.meijutt.tv/new100.html 中的數(shù)據(jù),使用以下命令:
scrapystartprojectmeiju
創(chuàng)建爬蟲程序
cdmeiju
scrapygenspidermeijuSpidermeijutt.tv
?
其中:
? ? meijuSpider為爬蟲文件名
? ? meijutt.com為爬取網(wǎng)址的域名
創(chuàng)建Scrapy工程后, 會自動創(chuàng)建多個文件,下面來簡單介紹一下各個主要文件的作用:
scrapy.cfg:
? ? 項(xiàng)目的配置信息,主要為Scrapy命令行工具提供一個基礎(chǔ)的配置信息。(真正爬蟲相關(guān)的配置信息在settings.py文件中)
items.py:
? ? 設(shè)置數(shù)據(jù)存儲模板,用于結(jié)構(gòu)化數(shù)據(jù),如:Django的Model
pipelines:
? ? 數(shù)據(jù)處理行為,如:一般結(jié)構(gòu)化的數(shù)據(jù)持久化
settings.py:
? ? 配置文件,如:遞歸的層數(shù)、并發(fā)數(shù),延遲下載等
spiders:
? ? 爬蟲目錄,如:創(chuàng)建文件,編寫爬蟲規(guī)則
注意:一般創(chuàng)建爬蟲文件時,以網(wǎng)站域名命名
2. 定義Item
Item是保存爬取到的數(shù)據(jù)的容器;其使用方法和python字典類似,雖然我們可以在Scrapy中直接使用dict,但是 Item提供了額外保護(hù)機(jī)制來避免拼寫錯誤導(dǎo)致的未定義字段錯誤;
類似ORM中的Model定義字段,我們可以通過scrapy.Item 類來定義要爬取的字段。
importscrapy
?
classMeijuItem(scrapy.Item):
name=scrapy.Field()
3. 編寫爬蟲
# -*- coding: utf-8 -*-
importscrapy
fromlxmlimportetree
frommeiju.itemsimportMeijuItem
?
classMeijuspiderSpider(scrapy.Spider):
# 爬蟲名
name='meijuSpider'
# 被允許的域名
allowed_domains= ['meijutt.tv']
# 起始爬取的url
start_urls= ['http://www.meijutt.tv/new100.html']
?
# 數(shù)據(jù)處理
defparse(self,response):
# response響應(yīng)對象
# xpath
mytree=etree.HTML(response.text)
movie_list=mytree.xpath('//ul[@class="top-list? fn-clear"]/li')
?
formovieinmovie_list:
name=movie.xpath('./h5/a/text()')
?
# 創(chuàng)建item(類字典對象)
item=MeijuItem()
item['name'] =name
yielditem
?
啟用一個Item Pipeline組件
為了啟用Item Pipeline組件,必須將它的類添加到 settings.py文件ITEM_PIPELINES 配置修改settings.py,并設(shè)置優(yōu)先級,分配給每個類的整型值,確定了他們運(yùn)行的順序,item按數(shù)字從低到高的順序,通過pipeline,通常將這些數(shù)字定義在0-1000范圍內(nèi)(0-1000隨意設(shè)置,數(shù)值越低,組件的優(yōu)先級越高)
ITEM_PIPELINES= {
'meiju.pipelines.MeijuPipeline':300,
}
設(shè)置UA
在setting.py中設(shè)置USER_AGENT的值
USER_AGENT='Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
?
4. 編寫 Pipeline 來存儲提取到的Item(即數(shù)據(jù))
classSomethingPipeline(object):
def__init__(self):
# 可選實(shí)現(xiàn),做參數(shù)初始化等
? ? defprocess_item(self,item,spider):
# item (Item 對象) – 被爬取的item
# spider (Spider 對象) – 爬取該item的spider
# 這個方法必須實(shí)現(xiàn),每個item pipeline組件都需要調(diào)用該方法,
# 這個方法必須返回一個 Item 對象,被丟棄的item將不會被之后的pipeline組件所處理。
returnitem
?
defopen_spider(self,spider):
# spider (Spider 對象) – 被開啟的spider
# 可選實(shí)現(xiàn),當(dāng)spider被開啟時,這個方法被調(diào)用。
?
defclose_spider(self,spider):
# spider (Spider 對象) – 被關(guān)閉的spider
# 可選實(shí)現(xiàn),當(dāng)spider被關(guān)閉時,這個方法被調(diào)用
運(yùn)行爬蟲:
scrapycrawlmeijuSpider
?
# nolog模式
scrapycrawlmeijuSpider--nolog
scrapy保存信息的最簡單的方法主要有這幾種,-o 輸出指定格式的文件,命令如下:
scrapycrawlmeijuSpider-omeiju.json
scrapycrawlmeijuSpider-omeiju.csv
scrapycrawlmeijuSpider-omeiju.xml