Scrapy 爬蟲(chóng)框架介紹
今天我們開(kāi)始學(xué)習(xí)一門(mén)新的 Python 框架:Scrapy。Scrapy 是一個(gè)爬蟲(chóng)框架,能幫助我們簡(jiǎn)化網(wǎng)絡(luò)爬蟲(chóng)開(kāi)發(fā),用最少的代碼完成爬蟲(chóng)項(xiàng)目,同時(shí)具備完整爬蟲(chóng)功能。
1. 爬蟲(chóng)簡(jiǎn)介
網(wǎng)絡(luò)爬蟲(chóng)是一段具有特殊含義的代碼,其功能是模擬用戶在瀏覽器上的操作,發(fā)送 HTTP 請(qǐng)求,接收數(shù)據(jù),然后解析并保存數(shù)據(jù),方便其他應(yīng)用程序使用和分析。
這個(gè)過(guò)程中間包含了許多自動(dòng)化的操作,若使用得當(dāng),可以產(chǎn)生大量的經(jīng)濟(jì)價(jià)值以及幫助我們減少繁雜的工作。
互聯(lián)網(wǎng)上每天都會(huì)有無(wú)數(shù)的爬蟲(chóng)在網(wǎng)絡(luò)上游走,獲取相應(yīng)網(wǎng)站的數(shù)據(jù)。這些爬蟲(chóng)和人一樣,有好有壞,有正義的,也有邪惡的。比如百度 Spider 等搜索引擎爬蟲(chóng),為我們提供了信息檢索的最新數(shù)據(jù),我們能通過(guò)搜索關(guān)鍵字找到相應(yīng)的網(wǎng)站,正是得益于百度 Spider 每天孜孜不倦的工作。搬運(yùn)相應(yīng)網(wǎng)站的地址和更新相應(yīng)的信息數(shù)據(jù),這也是必要的爬蟲(chóng),許多網(wǎng)站也樂(lè)于被百度爬蟲(chóng)抓取最新數(shù)據(jù)。
但是也存在許多惡意爬蟲(chóng),長(zhǎng)時(shí)間、大規(guī)模的請(qǐng)求特定網(wǎng)站數(shù)據(jù),給網(wǎng)站服務(wù)器造成了巨大的壓力,影響正常用戶請(qǐng)求,這也是許多網(wǎng)站討厭爬蟲(chóng)并積極設(shè)置反爬蟲(chóng)策略的原因。
對(duì)于個(gè)人開(kāi)發(fā)者而言,學(xué)好爬蟲(chóng)技術(shù),對(duì)于個(gè)人成長(zhǎng)方面有著極大的好處:
- 鍛煉個(gè)人技能,及時(shí)體驗(yàn)技術(shù)帶來(lái)的好處:使用簡(jiǎn)單的幾行 Python 代碼就能獲取網(wǎng)站數(shù)據(jù),這樣的學(xué)習(xí)曲線遠(yuǎn)勝于使用 C/C++ 進(jìn)行爬蟲(chóng)開(kāi)發(fā)。這也是很多人選擇 Python 開(kāi)發(fā)爬蟲(chóng)的原因;
- 在工作和生活上有時(shí)候能帶來(lái)極大的好處:比如收集數(shù)據(jù),完成畢業(yè)論文;比如開(kāi)-發(fā)一款 12306 搶票助手,解決回家搶票困難的問(wèn)題;又或者抓取股票交易數(shù)據(jù),幫助我們分析股票走勢(shì)等等。事實(shí)上,已經(jīng)有很多人做了這些工作并在 Github 上進(jìn)行了開(kāi)源。
事實(shí)上,爬蟲(chóng)的應(yīng)用還有很多,就不在此逐一說(shuō)明了。接下來(lái)我們介紹 Python 的爬蟲(chóng)框架以及使用爬蟲(chóng)框架進(jìn)行開(kāi)發(fā)的好處。
2. 各種爬蟲(chóng)框架優(yōu)缺點(diǎn)對(duì)比
下面我們介紹開(kāi)源界中幾個(gè)關(guān)注度比較高的 Python 爬蟲(chóng)框架。所謂關(guān)注度高包括 Github 上的點(diǎn)贊數(shù)以及文檔的豐富程度。
2.1 Scrapy
Scrapy 框架大概是最火的 Python 爬蟲(chóng)框架了,這一點(diǎn)可以從它的 Github 點(diǎn)贊數(shù)看出來(lái):38k !單純從這個(gè)數(shù)字就可以看出這是一個(gè)超級(jí)熱門(mén)的框架了。
在 Scrapy 的官方文檔中,對(duì)該框架是這么介紹的:
Scrapy is an application framework for crawling web sites and extracting structured data which can be used for a wide range of useful applications, like data mining, information processing or historical archival.
簡(jiǎn)單翻譯下就是:
Scrapy 是一個(gè)為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫(xiě)的應(yīng)用框架。盡管如此,它也可以作為一個(gè)通用的 Web 爬蟲(chóng)框架來(lái)開(kāi)發(fā)爬蟲(chóng)項(xiàng)目。它基于 Twisted 這個(gè)流行的異步處理框架,因此具有較高的性能。開(kāi)發(fā)者只需要定制開(kāi)發(fā)幾個(gè)模塊就可以輕松的實(shí)現(xiàn)一個(gè)高性能爬蟲(chóng),用來(lái)抓取網(wǎng)頁(yè)內(nèi)容,非常方便。下面我總結(jié)了一下 Scrapy 框架的幾個(gè)優(yōu)點(diǎn):
- Scrapy 是異步的,且可以靈活調(diào)節(jié)并發(fā)量;
- 采取可讀性更強(qiáng)的 Xpath,解析網(wǎng)頁(yè)速度快;
- 有統(tǒng)一的 Middleware 過(guò)濾器;
- 支持 Shell 方式,方便獨(dú)立調(diào)試;
- 通過(guò)管道的方式存入數(shù)據(jù)庫(kù),靈活方便且可保存為多種形式。
當(dāng)然,Scrapy 框架也是有不少缺點(diǎn)的,比較明顯的有如下幾點(diǎn):
-
本身無(wú)法實(shí)現(xiàn)分布式爬蟲(chóng);
-
自身去重效果差,消耗內(nèi)存,且不能持久化;
-
無(wú)法獲取需要執(zhí)行 js 才能獲取數(shù)據(jù)的網(wǎng)頁(yè);
-
基于 twisted 框架,如果執(zhí)行出錯(cuò)是不會(huì)停掉其他任務(wù)的,這回導(dǎo)致 Scrapy 在爬取數(shù)據(jù)出錯(cuò)后難以察覺(jué)。
基于 Scrapy 的這些缺點(diǎn)產(chǎn)生了許多框架的插件來(lái)解決。比如 scrapy-redis 解決了 Scrapy 框架的分布式爬取問(wèn)題; scrapy-splash 插件可以抓取 js 動(dòng)態(tài)渲染內(nèi)容等等。后面我們也會(huì)基于這些插件開(kāi)發(fā)一個(gè)完整的分布式爬蟲(chóng)項(xiàng)目來(lái)幫助我們體驗(yàn)爬蟲(chóng)的魅力。
2.2 Pyspider
pyspider 是一款國(guó)人編寫(xiě)的功能強(qiáng)大的網(wǎng)絡(luò)爬蟲(chóng)系統(tǒng),能在瀏覽器界面上進(jìn)行腳本的編寫(xiě),功能的調(diào)度和爬取結(jié)果的實(shí)時(shí)查看,后端使用常用的數(shù)據(jù)庫(kù)進(jìn)行爬取結(jié)果的存儲(chǔ),還能定時(shí)設(shè)置任務(wù)與任務(wù)優(yōu)先級(jí)等。總的來(lái)說(shuō),它的特點(diǎn)如下:
-
具有強(qiáng)大的 webui 界面,并且支持腳本編輯,任務(wù)監(jiān)控,項(xiàng)目管理和結(jié)果查看;
-
數(shù)據(jù)后臺(tái)支持 MySQL、MongoDB、Reids、SQLite、Elasticsearch 和 PostgreSQL 等主流關(guān)系型和非關(guān)系型數(shù)據(jù)庫(kù);
-
消息隊(duì)列支持 RabbitMQ、Redis 等;
-
支持任務(wù)優(yōu)先級(jí),定時(shí),失敗重試等調(diào)度方案;
-
支持分布式架構(gòu),抓取 js 頁(yè)面。
Pyspider 也存在一些明顯的問(wèn)題:豐富的文檔、成熟的社區(qū),這些都是 pyspider 欠缺的,也造成了 Pyspider 不如 Scrapy 流行的重要原因之一。但 Pyspider 在簡(jiǎn)潔易用性上卻是勝過(guò) Scrapy 的,很多初學(xué)者也會(huì)非常喜歡它提供的 webui 頁(yè)面,這也是該框架得以流行的原因之一。
2.3 Cola
Cola 是一個(gè)分布式的爬蟲(chóng)框架,對(duì)于用戶來(lái)說(shuō),只需編寫(xiě)幾個(gè)特定的函數(shù),而無(wú)需關(guān)注分布式運(yùn)行的細(xì)節(jié)。任務(wù)會(huì)自動(dòng)分配到多臺(tái)機(jī)器上,整個(gè)過(guò)程對(duì)用戶是透明的。
但是從 Github 上的用戶的關(guān)注度來(lái)看,相比上面兩個(gè)框架而言,差了不少。整個(gè)項(xiàng)目的主要貢獻(xiàn)者只有2個(gè)人,且上次一發(fā)布 release 版本還是2015年的上古時(shí)代。這些都已經(jīng)充分說(shuō)明了 Cola 框架正在逐漸走向衰退,不建議在生產(chǎn)環(huán)境中使用,其潛在的 Bug 和相關(guān)安全風(fēng)險(xiǎn)無(wú)法得到及時(shí)的更新和修復(fù),但是作為學(xué)習(xí)爬蟲(chóng)框架的參考資料還是不錯(cuò)的,深入研究這樣一個(gè)框架的源碼能收獲不少知識(shí)。
3. 為什么要學(xué)習(xí) Scrapy?
Scrapy 是一款性能強(qiáng)大爬蟲(chóng)框架,基于 Scrapy 我們可以快速開(kāi)發(fā)出高性能的爬蟲(chóng)。此外,由于 Scrapy 框架的高度可擴(kuò)展性,我們可以在該框架簡(jiǎn)單改造就能實(shí)現(xiàn)自己的業(yè)務(wù)需求。例如 Scrapy-Redis 插件,短短幾千行代碼就實(shí)現(xiàn) Scrapy 框架的分布式功能。
如果能熟練掌握 Scrapy 框架,我們會(huì)具備如下的優(yōu)勢(shì):
- 基于 Scrapy 框架快速開(kāi)發(fā)出高性能爬蟲(chóng),不用擔(dān)心爬蟲(chóng)性能問(wèn)題;
- 豐富的 Scrapy 文檔、良好的社區(qū)以及龐大的用戶群體。這些都是我們選擇 Scrapy 框架的理由;
- 熟練掌握 Scrapy 框架后,可以深入學(xué)習(xí) Scrapy 框架源碼,了解一個(gè)完整爬蟲(chóng)框架的組成;在架構(gòu)設(shè)計(jì)和代碼風(fēng)格上,Scrapy 都是極為優(yōu)秀的。作為初學(xué)者的我們可以從中收獲不少,特別是關(guān)于 Twisted 框架的運(yùn)用;
- 高度可定制化。這是 Scrapy 框架的一個(gè)極大優(yōu)勢(shì),通過(guò)簡(jiǎn)單改造 Scrapy,我們就能實(shí)現(xiàn)特點(diǎn)功能的爬蟲(chóng)。如 Scrapy-Redis 插件,不過(guò)數(shù)千行代碼,就將 Scrapy 框架擴(kuò)展成分布式,而且是即插即用型,不用改動(dòng) Scrapy 源碼。
看到這些特點(diǎn)后,你還有什么理由不學(xué)習(xí) Scrapy 框架呢?
4. 學(xué)習(xí)基礎(chǔ)
為了學(xué)好該框架以及熟練使用 Scrapy 開(kāi)發(fā)爬蟲(chóng)項(xiàng)目,我們需要具備以下基礎(chǔ):
- 簡(jiǎn)單的網(wǎng)頁(yè)基礎(chǔ),HTML/CSS等;
- Python 基礎(chǔ);
- 簡(jiǎn)單的計(jì)算機(jī)網(wǎng)絡(luò)基礎(chǔ),比如了解 HTTP 協(xié)議、TCP/IP 協(xié)議等;
本課程會(huì)假定你已經(jīng)了解或者熟悉上述基礎(chǔ)知識(shí),并在后面不會(huì)對(duì)一些簡(jiǎn)單的問(wèn)題作出解釋?zhuān)攸c(diǎn)放到剖析這個(gè)框架并熟練掌握。
5. 小結(jié)
本小節(jié)簡(jiǎn)單介紹了爬蟲(chóng)知識(shí)以及在 Python 中比較流行的爬蟲(chóng)框架,重點(diǎn)介紹了 Python 中大火的 Scrapy 框架,這也是我們接下來(lái)學(xué)習(xí)的重點(diǎn)。緊接著描述了學(xué)習(xí) Scrapy 框架必備的一些基礎(chǔ)知識(shí) 。從下一節(jié)起,將開(kāi)始我們正式的剖析 Scrapy 框架之旅,祝大家旅途愉快。