Scrapy
Scrapy是用純Python實(shí)現(xiàn)一個(gè)為了爬取網(wǎng)站數(shù)據(jù)、提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架,用途非常廣泛。
框架的力量,用戶只需要定制開發(fā)幾個(gè)模塊就可以輕松的實(shí)現(xiàn)一個(gè)爬蟲,用來抓取網(wǎng)頁內(nèi)容以及各種圖片,非常之方便。
Scrapy 使用了 Twisted['tw?st?d] 異步網(wǎng)絡(luò)框架來處理網(wǎng)絡(luò)通訊,可以加快我們的下載速度,不用自己去實(shí)現(xiàn)異步框架,并且包含了各種中間件接口,可以靈活的完成各種需求。
Scrapy框架同步異步展示圖:

異步:調(diào)用在發(fā)出之后,這個(gè)調(diào)用就直接返回,不管有無結(jié)果
非阻塞:關(guān)注的是程序在等待調(diào)用結(jié)果(消息,返回值)時(shí)的狀態(tài),指在不能立刻得到結(jié)果之前,該調(diào)用不會(huì)阻塞當(dāng)前線程
Scrapy框架架構(gòu)圖

Scrapy的各種功能:
Scrapy Engine(引擎): 負(fù)責(zé)Spider、ItemPipeline、Downloader、Scheduler中間的通訊,信號(hào)、數(shù)據(jù)傳遞等。
Scheduler(調(diào)度器): 它負(fù)責(zé)接受引擎發(fā)送過來的Request請求,并按照一定的方式進(jìn)行整理排列,入隊(duì),當(dāng)引擎需要時(shí),交還給引擎。
Downloader(下載器):負(fù)責(zé)下載Scrapy Engine(引擎)發(fā)送的所有Requests請求,并將其獲取到的Responses交還給Scrapy Engine(引擎),由引擎交給Spider來處理,
Spider(爬蟲):它負(fù)責(zé)處理所有Responses,從中分析提取數(shù)據(jù),獲取Item字段需要的數(shù)據(jù),并將需要跟進(jìn)的URL提交給引擎,再次進(jìn)入Scheduler(調(diào)度器),
Item Pipeline(管道):它負(fù)責(zé)處理Spider中獲取到的Item,并進(jìn)行進(jìn)行后期處理(詳細(xì)分析、過濾、存儲(chǔ)等)的地方.
Downloader Middlewares(下載中間件):可以自定義擴(kuò)展下載功能的組件(代理、cokies等)。
Spider Middlewares(Spider中間件):可以自定擴(kuò)展和操作引擎和Spider中間通信的功能組件(比如進(jìn)入Spider的Responses;和從Spider出去的Requests)
Scrapy主要包括了以下組件:
引擎(Scrapy)
用來處理整個(gè)系統(tǒng)的數(shù)據(jù)流處理, 觸發(fā)事務(wù)(框架核心)
調(diào)度器(Scheduler)
用來接受引擎發(fā)過來的請求, 壓入隊(duì)列中, 并在引擎再次請求的時(shí)候返回. 可以想像成一個(gè)URL(抓取網(wǎng)頁的網(wǎng)址或者說是鏈接)的優(yōu)先隊(duì)列, 由它來決定下一個(gè)要抓取的網(wǎng)址是什么, 同時(shí)去除重復(fù)的網(wǎng)址
下載器(Downloader)
用于下載網(wǎng)頁內(nèi)容, 并將網(wǎng)頁內(nèi)容返回給蜘蛛(Scrapy下載器是建立在twisted這個(gè)高效的異步模型上的)
爬蟲(Spiders)
爬蟲是主要干活的, 用于從特定的網(wǎng)頁中提取自己需要的信息, 即所謂的實(shí)體(Item)。用戶也可以從中提取出鏈接,讓Scrapy繼續(xù)抓取下一個(gè)頁面
項(xiàng)目管道(Pipeline)
負(fù)責(zé)處理爬蟲從網(wǎng)頁中抽取的實(shí)體,主要的功能是持久化實(shí)體、驗(yàn)證實(shí)體的有效性、清除不需要的信息。當(dāng)頁面被爬蟲解析后,將被發(fā)送到項(xiàng)目管道,并經(jīng)過幾個(gè)特定的次序處理數(shù)據(jù)。
下載器中間件(Downloader Middlewares)
位于Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請求及響應(yīng)。
爬蟲中間件(Spider Middlewares)
介于Scrapy引擎和爬蟲之間的框架,主要工作是處理蜘蛛的響應(yīng)輸入和請求輸出。
調(diào)度中間件(Scheduler Middewares)
介于Scrapy引擎和調(diào)度之間的中間件,從Scrapy引擎發(fā)送到調(diào)度的請求和響應(yīng)。
Scrapy運(yùn)行流程大概如下:
引擎從調(diào)度器中取出一個(gè)鏈接(URL)用于接下來的抓取
引擎把URL封裝成一個(gè)請求(Request)傳給下載器
下載器把資源下載下來,并封裝成應(yīng)答包(Response)
爬蟲解析Response
解析出實(shí)體(Item),則交給實(shí)體管道進(jìn)行進(jìn)一步的處理
解析出的是鏈接(URL),則把URL交給調(diào)度器等待抓取
其實(shí)Scrapy框架需要自己手寫的東西只有Spider(爬蟲)和Item Pipeline(管道)倆個(gè)模塊,但是對于下載失敗的url,scrapy會(huì)重新發(fā)起請求,只有當(dāng)調(diào)度器中不存在任何request了,整個(gè)程序才會(huì)停止。
具體scrapy的安裝步驟:
Scrapy框架官方網(wǎng)址:‘http://doc.scrapy.org/en/latest’
Scrapy中文維護(hù)站點(diǎn):’http://scrapy-chs.readthedocs.io/zh_CN/latest/index.html’
Windows 安裝方式
Python 3
升級pip版本:
pip3 install --upgrade pip
通過pip 安裝 Scrapy 框架
pip3 install Scrapy
Ubuntu 安裝方式
通過pip3 安裝 Scrapy 框架
sudo pip3 install scrapy
如果安裝不成功再試著添加這些依賴庫:
安裝非Python的依賴
sudo apt-get install python3-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev
基本創(chuàng)建項(xiàng)目的命令是:
1.scrapy startproject ‘項(xiàng)目名稱’
2.?cd sp1
?3.? scrapy genspider xiaohuar(項(xiàng)目名字,運(yùn)行項(xiàng)目的時(shí)候用:scrapy?crawl?xiaohuar) xiaohuar.com(域名)?
? 4.scrapy genspider baidu baidu.com (爬蟲文件)
Scrapy每個(gè)文件主要的作用:

items.py ? ?設(shè)置數(shù)據(jù)存儲(chǔ)模板,用于結(jié)構(gòu)化數(shù)據(jù),如:Django的Model
pipelines ? ?數(shù)據(jù)處理行為,如:一般結(jié)構(gòu)化的數(shù)據(jù)持久化
settings.py 配置文件,如:遞歸的層數(shù)、并發(fā)數(shù),延遲下載等
spiders ? ? ?爬蟲目錄,如:創(chuàng)建文件,編寫爬蟲規(guī)則
.實(shí)施爬蟲
定義Item ? ? ??
?Item 是用來保存爬取到的數(shù)據(jù)的容器,創(chuàng)建一個(gè) scrapy.Item 類, 并且定 義類型為 scrapy.Field 的類屬性來定義一個(gè)Item。將需要爬取的內(nèi)容與Field()定 義的屬性對應(yīng)。?

.爬蟲(spider)
編寫第一個(gè)爬蟲(Spider) 創(chuàng)建一個(gè)繼承?scrapy.Spider?的子類Douban,且定義以下三個(gè)屬性:
(1)name: 用于區(qū)別Spider。 該名字必須是唯一的---》
(2)start_urls: 包含了Spider在啟動(dòng)時(shí)進(jìn)行爬取的url列表。 因此,第一個(gè)被獲取到的 頁面將是其中之一。 后續(xù)的URL則從初始的URL獲取到的數(shù)據(jù)中提取。
(3)parse()?是spider的一個(gè)方法。 被調(diào)用時(shí),每個(gè)初始URL完成下載后生成的 Response?對象將會(huì)作為唯一的參數(shù)傳遞給該函數(shù)。 該方法負(fù)責(zé)解析返回的數(shù)據(jù) (response data),提取數(shù)據(jù)(生成item)以及生成需要進(jìn)一步處理的URL的?Request?對象?
編寫第一個(gè)爬蟲

數(shù)據(jù)持久化:
在setting.py文件中:


在pipelines.py文件中:
