還等什么歼狼,Scrapy啟動,爬取開始芥炭!
目標(biāo)網(wǎng)站
這里我們選取的目標(biāo)網(wǎng)站是我常逛的干貨集中營漓库,而要爬取的就是她:
準(zhǔn)確的說是她們,點擊右上角“今日力薦”园蝠,可以跳轉(zhuǎn)至往期“干貨”渺蒿,這里就不再貼圖了,下面我們先簡單說下Scrapy的架構(gòu)和各部分功能彪薛。
架構(gòu)說明
- Scrapy Engine(引擎): 負(fù)責(zé)Spider茂装、ItemPipeline、Downloader善延、Scheduler中間的通訊训唱,信號、數(shù)據(jù)傳遞等挚冤。
- Scheduler(調(diào)度器): 它負(fù)責(zé)接受引擎發(fā)送過來的Request請求况增,并按照一定的方式進(jìn)行整理排列,入隊训挡,當(dāng)引擎需要時澳骤,交還給引擎歧强。
- 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ì)分析棋枕、過濾白修、存儲等)的地方。
- Downloader Middlewares(下載中間件):你可以當(dāng)作是一個可以自定義擴展下載功能的組件重斑。
- Spider Middlewares(Spider中間件):你可以理解為是一個可以自定擴展和操作引擎和Spider中間通信的功能組件(比如進(jìn)入Spider的Responses;和從Spider出去的Requests)
下面正式開始爬取工作兵睛。
創(chuàng)建項目
在工作目錄shift+鼠標(biāo)右鍵打開命令窗口,輸入
scrapy startproject girls
之后一個名為“girls”的Scrapy項目就已經(jīng)創(chuàng)建了窥浪。
打開PyCharm選擇“open”方式打開已創(chuàng)建項目(這里不建議用把項目直接拖到PyCharm的方式打開祖很,筆者因此遇到了已經(jīng)下好的庫無法載入的問題)。好了漾脂,讓我們看下載入好的項目目錄:
- scrapy.cfg: 項目的配置文件。
- girls/:項目的Python模塊骨稿,后續(xù)代碼在該目錄添加笨鸡。
- girls/items.py:項目中的item文件,保存爬取數(shù)據(jù)的容器啊终。
- girls/pipelines.py:項目中的pipelines文件,用于處理獲取的item傲须。
- girls/settings.py:項目的設(shè)置文件蓝牲。
- girls/spiders/:放置spider代碼的目錄。
明確目標(biāo)
通過定義Item明確爬取目標(biāo)泰讽。Item使用方法類似Python的字典例衍,另外它還提供了額外保護(hù)機制防止拼寫錯誤。這里只需要爬取圖片已卸,所以源碼為:
import scrapy
class GirlsItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 圖片url
image_urls = scrapy.Field()
# 圖片信息
images = scrapy.Field()
- image_urls :圖片url佛玄,爬蟲(spider)抓取項目后會將對應(yīng)url放入image_urls 中
- images :圖片信息,圖片下載完后更新到images結(jié)構(gòu)中累澡。它包含一個字典列表梦抢,其中包括下載路徑、源抓取地址(image_urls中獲得)愧哟、圖片校驗碼奥吩,并且圖片順序與image_urls保持一致哼蛆。如果下載失敗,將記錄錯誤信息霞赫,不再出現(xiàn)在images 中腮介。
(這里用到了ImagesPipeline
,下面會詳情講)
制作爬蟲
即編寫girls/spiders/目錄下的spider端衰,spider類定義了爬取網(wǎng)站的邏輯叠洗,包括爬取的動作(如是否跟進(jìn)鏈接),將網(wǎng)頁內(nèi)容提取成結(jié)構(gòu)化數(shù)據(jù)(爬取Item)等旅东。
這里建議通過命令直接生成spider文件:
點擊打開PyCharm左下角Terminal窗口灭抑,輸入
scrapy genspider girl gank.io/
在girls/spiders/目錄下會生成對應(yīng)girl.py文件,文件內(nèi)容:
# -*- coding: utf-8 -*-
import scrapy
class GirlSpider(scrapy.Spider):
name = 'girl'
allowed_domains = ['gank.io/']
start_urls = ['http://gank.io//']
def parse(self, response):
pass
當(dāng)然手動創(chuàng)建也是一樣的效果玉锌,命令只是省去了書寫樣板代碼過程名挥。解釋下代碼:
- name:爬蟲名字,必須且唯一主守,后續(xù)命令也以此名字為準(zhǔn)禀倔。
- allowed_domains:爬蟲允許的域名列表,域名不在列表時將不再跟進(jìn)参淫,可選救湖。
- start_urls:爬取的url列表,未制定特定url時涎才,爬蟲從該列表開始爬取鞋既。
- parse(self, response):負(fù)責(zé)處理response并返回數(shù)據(jù)以及跟進(jìn)的url(如果需要的話)。
在生成文件基礎(chǔ)上添加我們的爬取邏輯:
# -*- coding: utf-8 -*-
import scrapy
from girls.items import GirlsItem
class GirlSpider(scrapy.Spider):
name = 'girl'
allowed_domains = []
start_urls = ['http://gank.io//']
def parse(self, response):
item = GirlsItem()
item["image_urls"] = response.xpath("/html/body/div[1]/div[1]/div[2]/p[1]/img/@src").extract()
print(item)
yield item
new_url = response.xpath("/html/body/div[1]/div[1]/div[1]/div[2]/p/a/@href").extract_first()
if new_url:
# 將相對路徑轉(zhuǎn)為絕對路徑
new_url = response.urljoin(new_url)
print(new_url)
yield scrapy.Request(new_url, callback=self.parse)
簡單說下代碼中網(wǎng)頁元素xpath獲取方法耍铜,這里用的瀏覽器是Chrome邑闺。
- 在想要獲取xpath的網(wǎng)頁元素上點擊右鍵,選擇檢查棕兼;
-
在被選擇的標(biāo)簽上右鍵陡舅,Copy →Copy XPath,
粘貼至代碼中即可伴挚。
存儲內(nèi)容
這里主要指設(shè)計管道( item pipeline)存儲爬取到的內(nèi)容靶衍,即上邊提到的ImagesPipeline
。
ImagesPipeline即Scrapy提供的一個item pipeline茎芋,用來下載某個特定項目中的圖片并保存到本地颅眶,并且具有如下特點:
- 將所有下載的圖片轉(zhuǎn)換成通用的格式(JPG)和模式(RGB)
- 避免重新下載最近已經(jīng)下載過的圖片
- 縮略圖生成
- 檢測圖像的寬/高,確保它們滿足最小限制
這里如果需要生成縮略圖田弥,請下載Pillow庫涛酗,下載方法“安裝篇”里有提到。
使用ImagesPipeline除了items.py中的代碼外,只需要在settings.py配置相關(guān)設(shè)置即可煤杀,貼上源碼根據(jù)需求設(shè)置:
# 開啟圖片管道 ImagesPipeline地址項目實際地址為準(zhǔn)
ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 300}
# 設(shè)置圖片存儲目錄眷蜈,一個有效的文件夾
IMAGES_STORE = 'girls/bitmap'
# 圖片開始下載延時
# DOWNLOAD_DELAY = 0.25
#縮略圖的尺寸,設(shè)置這個值就會產(chǎn)生縮略圖
# IMAGES_THUMBS = {
# 'small': (50, 50),
# 'big': (200, 200),
# }
# 90天的圖片失效期限
# 避免下載最近已經(jīng)下載的圖片
# IMAGES_EXPIRES = 90
# 濾出小圖片
# IMAGES_MIN_HEIGHT = 110
# IMAGES_MIN_WIDTH = 110
注意:開啟圖片管道設(shè)置ImagesPipeline地址應(yīng)以項目實際地址為準(zhǔn)這里是scrapy.pipelines.images.ImagesPipeline
沈自,這點官方中文文檔有誤酌儒。
另外如果需要定制圖片管道請參考官方文檔的 實現(xiàn)定制圖片管道,這里不再贅述枯途。
開始爬取(?ω?)
雖然直接在命令行中輸入命令即可開始爬取忌怎,但是既然我們使用了PyCharm不妨使用IDE的方式:
- 在scrapy.cfg文件同級目錄創(chuàng)建start.py文件,輸入
# -*- coding:utf-8 -*-
from scrapy import cmdline
cmdline.execute("scrapy crawl girl".split())
-
右上角
左邊或者Run
菜單中選擇 -
彈出菜單點擊加+號酪夷,選擇
Python
-
做如下設(shè)置
設(shè)置完榴啸,OK結(jié)束。
-
點擊右上角
即可開始爬取晚岭。
稍等片刻圖片就爬取完啦鸥印,如圖?(????ω????)?
總結(jié)
綜上可見一個標(biāo)準(zhǔn)的Scrapy爬取流程是:
- 創(chuàng)建項目 (scrapy startproject xxx):新建一個新的爬蟲項目
- 明確目標(biāo) (編寫items.py):明確你想要抓取并存儲的目標(biāo)
- 制作爬蟲 (spiders/xxspider.py):制作爬蟲,明確爬取的網(wǎng)頁元素及爬取動作
- 存儲內(nèi)容 (pipelines.py):設(shè)計管道存儲爬取內(nèi)容
那么以上各個部分在爬取過程中是如何運行和配合的呢坦报?
結(jié)合上面提到的架構(gòu)圖可知:
- Scrapy引擎從爬蟲(Spider)文件中獲取開始的url库说,并交由調(diào)度器和下載器處理,處理好后得到的response交還爬蟲片择;
- 爬蟲根據(jù)爬蟲文件中設(shè)置的爬取動作潜的,爬取
image_urls
并儲存至items中,需要跟進(jìn)的url提交給引擎字管; - Scrapy引擎將items中
image_urls
交給管道(Item Pipeline)處理啰挪,跟進(jìn)的url交給調(diào)度器; - 管道這里根據(jù)ImagesPipeline及settings.py中的設(shè)置處理并將
image_urls
通過引擎交由調(diào)度器和下載器下載嘲叔,項目會在這個特定的管道階段保持“l(fā)ocker”的狀態(tài)亡呵,直到完成圖片的下載(或者由于某些原因未完成下載),下載完后硫戈,圖片信息更新到images
中锰什。之后調(diào)度器根據(jù)需跟進(jìn)的url從1.
開始循環(huán),直到調(diào)度器中不再有任何request掏愁,爬取結(jié)束歇由。
參考文章:
官方文檔:https://scrapy-chs.readthedocs.io/zh_CN/0.24/index.html
Scrapy 入門教程:http://www.runoob.com/w3cnote/scrapy-detail.html
Scrapy爬取美女:https://www.cnblogs.com/qiyeboy/p/5428240.html