你懂Scrapy嗎?Scrapy大型爬蟲框架講解【一】
這是Scrapy爬蟲框架的***篇,本系列專題將包含以下內(nèi)容:
- 介紹Scrapy框架的主體以及各個(gè)組件的意義;
 - 舉實(shí)例講解其具體應(yīng)用。
 
開始***節(jié): 介紹Scrapy框架的主體以及各個(gè)組件的意義。
Scrapy是一個(gè)為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架。 可以應(yīng)用在包括數(shù)據(jù)挖掘,信息處理或存儲歷史數(shù)據(jù)等一系列的程序中。
其最初是為了 頁面抓取 (更確切來說, 網(wǎng)絡(luò)抓取 )所設(shè)計(jì)的, 也可以應(yīng)用在獲取API所返回的數(shù)據(jù)(例如 Amazon Associates Web Services ) 或者通用的網(wǎng)絡(luò)爬蟲。
安裝Scrapy需要一些依賴:
- Python
 - Python Package: pip and setuptools. 現(xiàn)在 pip 依賴 setuptools ,如果未安裝,則會(huì)自動(dòng)安裝setuptools 。
 - lxml. 大多數(shù)Linux發(fā)行版自帶了lxml。如果缺失,請查看 Installing lxml
 - OpenSSL. 除了Windows(請查看 平臺安裝指南)之外的系統(tǒng)都已經(jīng)提供。
 
當(dāng)安裝好這些依賴之后,只需要運(yùn)行pip install Scrapy,即可安裝完Scrapy。
然后運(yùn)行:
- scrapy startproject tutorial
 
即可自動(dòng)創(chuàng)建官方標(biāo)準(zhǔn)的代碼目錄。
- tutorial/
 - scrapy.cfg
 - tutorial/
 - __init__.py
 - items.py
 - pipelines.py
 - settings.py
 - spiders/
 - __init__.py
 - ...
 
其中:
- tutorial/: 該項(xiàng)目的python總模塊。
 - tutorial/items.py: 項(xiàng)目中的item文件,編寫爬取的字段名稱等;
 - tutorial/pipelines.py: 項(xiàng)目中的pipelines文件;
 - tutorial/settings.py: 項(xiàng)目的設(shè)置文件,較為重要;
 - tutorial/spiders/: 放置spider代碼的主目錄;
 
Scrapy整體架構(gòu)神圖:
Scrapy中的數(shù)據(jù)流由執(zhí)行引擎控制,其過程如下:
- 引擎打開一個(gè)網(wǎng)站(open a domain),找到處理該網(wǎng)站的Spider并向該spider請求***個(gè)要爬取的URL(s)。
 - 引擎從Spider中獲取到***個(gè)要爬取的URL并在調(diào)度器(Scheduler)以Request調(diào)度。
 - 引擎向調(diào)度器請求下一個(gè)要爬取的URL。
 - 調(diào)度器返回下一個(gè)要爬取的URL給引擎,引擎將URL通過下載中間件(請求(request)方向)轉(zhuǎn)發(fā)給下載器(Downloader)。
 - 一旦頁面下載完畢,下載器生成一個(gè)該頁面的Response,并將其通過下載中間件(返回(response)方向)發(fā)送給引擎。
 - 引擎從下載器中接收到Response并通過Spider中間件(輸入方向)發(fā)送給Spider處理。
 - Spider處理Response并返回爬取到的Item及(跟進(jìn)的)新的Request給引擎。
 - 引擎將(Spider返回的)爬取到的Item給Item Pipeline,將(Spider返回的)Request給調(diào)度器。
 - (從第二步)重復(fù)直到調(diào)度器中沒有更多地request,引擎關(guān)閉該網(wǎng)站。
 
以上是老生常談,下面談一些經(jīng)驗(yàn):
- 如果需要大批量分布式爬取,建議采用Redis數(shù)據(jù)庫存儲,可安裝scrapy-redis,使用redis數(shù)據(jù)庫來替換scrapy原本使用的隊(duì)列結(jié)構(gòu)(deque),并配合其它數(shù)據(jù)庫存儲,例如MySQL或者M(jìn)ongoDB,爬取效率將會(huì)極大提高。并且其自帶的dupefilter.py負(fù)責(zé)執(zhí)行requst的去重,使用redis的set數(shù)據(jù)結(jié)構(gòu),通過settings文件正確設(shè)置后,即便停止scrapy爬蟲,當(dāng)下次重新開始后也能自動(dòng)去重。原因就是在redis已經(jīng)存儲了request的信息。
 - 當(dāng)涉及到代理IP,Headers頭中間請求信息處理的時(shí)候,可以通過中間件Middleware來實(shí)現(xiàn)。Spider中間件是介入到Scrapy的spider處理機(jī)制的鉤子框架,可以添加代碼來處理發(fā)送給 Spiders的response及spider產(chǎn)生的item和request。
 - 合理設(shè)置settings文件,需要熟練掌握 settings 的各種設(shè)置。
 - 可以重新定義def start_requests(self)函數(shù)來加載cookie信息,form信息的提交用scrapy.FormRequest以及scrapy.FormRequest.from_response這兩個(gè)函數(shù),scrapy.FormRequest.from_response能實(shí)現(xiàn)自動(dòng)提交form數(shù)據(jù)。
 - 采用Scrapy+phantomJS,。 downloadMiddleware 對從 scheduler 送來的 Request 對象在請求之前進(jìn)行預(yù)處理,可以實(shí)現(xiàn)添加 headers, user_agent,還有 cookie 等功能 。但也可以通過中間件直接返回 HtmlResponse 對象,略過請求的模塊,直接扔給 response 的回調(diào)函數(shù)處理。
 
- class CustomMetaMiddleware(object):
 - def process_request(self,request,spider):
 - dcap = dict(DesiredCapabilities.PHANTOMJS)
 - dcap["phantomjs.page.settings.loadImages"] = False
 - dcap["phantomjs.page.settings.resourceTimeout"] = 10
 - driver = webdriver.PhantomJS("D:xx\xx",desired_capabilities=dcap)
 - driver.get(request.url)
 - body = driver.page_source.encode('utf8')
 - url = driver.current_url
 - driver.quit()
 - return HtmlResponse(request.url,body=body)
 
綜上,是對Scrapy的各個(gè)組件一些個(gè)人的經(jīng)驗(yàn)總結(jié)。















 
 
 






 
 
 
 