Windows 10家庭中文版,Python 3.6.4,Scrapy 1.5.0,html
在建立了爬蟲程序後,就能夠運行爬蟲程序了。Scrapy中介紹了幾種運行爬蟲程序的方式,列舉以下:python
-命令行工具之scrapy runspider(全局命令)react
-命令行工具之scrapy crawl(項目級命令)編程
-scrapy.crawler.CrawlerProcess多線程
-scrapy.crawler.CrawlerRunnerdom
注意,當系統中同時存在Python 二、Python 3時,孤的電腦直接執行scrapy命令使用的是Python 2,此時,須要在scrapy命令前添加「python3 -m」纔可使用Python 3,所以,請使用virtualenv創建虛擬環境運行scrapy等各類程序。異步
方式一:scrapy runspider命令(全局)scrapy
語法:scrapy runspider <spider_file.py>async
還有一些配置項,可使用scrapy runspider -h查看。分佈式
示例程序:文件名爲baidu_com.py
1 # -*- coding: utf-8 -*- 2 import scrapy 3 4 class BaiduComSpider(scrapy.Spider): 5 name = 'baidu.com' 6 allowed_domains = ['www.baidu.com'] 7 start_urls = ['https://www.baidu.com/'] 8 9 def parse(self, response): 10 yield { 11 'title': response.xpath('//title/text()').extract_first() 12 }
parse函數使用response.xpath獲取網頁<title>的文本:
方式二:scrapy crawl(項目級)
crawl是項目級命令,所以只能在某個Scrapy項目中使用。那麼,首先建立項目test070401:
使用tree命令查看建立的項目的結構:
剛剛建立的Scrapy項目的spiders目錄中只有__init__.py文件,那麼,將以前建立的baidu_com.py拷貝到此文件中:
如今,能夠在項目test070401中使用crawl命令執行爬蟲程序了。且慢,先看看crawl的語法:
scrapy crawl <spider>
注意,是<spider>而不是runspider命令的<spider_file.py>,準確的說<spider>是一個 爬蟲程序的名稱——爬蟲類裏面的name屬性(必須required,且在項目中具備惟一性unique)。
baidu_com.py裏面的爬蟲類的名稱是什麼呢?baidu.com
疑問:一個爬蟲文件裏面是否能夠創建多個爬蟲類呢?
那麼,執行下面的命令便可運行baidu_com.py裏面的爬蟲程序了:
scrapy crawl baidu.com
{
很尷尬,第一次執行竟然失敗了,沒找到!
嚴重懷疑是拷貝的問題,拷貝過來後 還須要作一些配置吧?配置在……settings.py裏面看看!
參考其它在項目裏面創建的爬蟲程序,發現settings.py中沒有其配置;spiders包下面的__init__.py文件呢?也沒發現其配置!
噩耗!怎麼辦?應該是能夠執行的啊!
暈~字母拼寫錯誤:baidu.com 拼寫成 badu.com!嚴重警告一次!
}
從新執行正確的命令:仍然沒有獲取到須要的數據,由於,robots協議的存在,程序被拒絕了!
警示:因此,抓取數據不必定會成功,由於還會被網站拒絕!可是,開發爬蟲程序時,必需要遵循相應的道德(規範)!
更多思考:
但是,爲什麼以前使用runspider抓取數據成功了呢?
再次使用runspider命令執行baidu_com.py:結果, 成功!
爲什麼如此 區別對待呢?
檢查二者啓動時的scrapy.crawler發現了不一樣:其中的crawl命令裏面包含ROBOTSTXT_OBEY爲True,代表其遵照站點的robots.txt協議!
那麼,測試中的站點的robots.txt是怎樣的呢?它幾乎拒絕了全部的爬蟲程序——Disallow!固然,baidu.com原本就是爬蟲了,怎麼會容許其它爬蟲爬取它呢?爬蟲爬取爬蟲,好奇怪!
固然,Scrapy項目是否遵照robots.txt協議,是能夠在settings.py中配置的,請參考官文Settings。
疑問:runspider、crawl命令是否能夠執行多個爬蟲程序呢?請測試!
------分割線------
學習Scrapy之初一直有一個困惑,爬蟲程序只能使用命令行來執行嗎?不能寫程序來執行嗎?固然能夠!
直到看了官文 Common Practices,此文中還介紹了一點關於分佈式爬取(Distributed crawls)的內容,但本篇博客不涉及。
方式三:CrawlerProcess
使用CrawlerProcess執行上面的baidu_com.py中的爬蟲類,程序runcp.py以下:
1 import scrapy 2 from scrapy.crawler import CrawlerProcess 3 from baidu_com import BaiduComSpider 4 5 # 建立一個CrawlerProcess對象 6 process = CrawlerProcess() # 括號中能夠添加參數 7 8 process.crawl(BaiduComSpider) 9 process.start()
執行程序runcp.py:成功,抓取到了須要的數據。
孤是在virtualenv中執行,因此,直接輸入runrc.py就能夠運行程序,不然,請使用python -m runrc.py。
注意,上面的程序是在Scrapy項目外執行的,若是是在項目內執行,
-可使用get_project_settings()函數獲取項目的一個Settings實例做爲CrawlerProcess的參數;
-傳遞給crawl(...)函數的能夠是項目內爬蟲程序的name屬性的值;
疑問,在項目內執行時,是否能夠 混合使用項目內外的爬蟲程序執行呢?既使用項目內的,也能夠經過導入使用項目外的。
疑問:
是否能夠執行多個爬蟲程序呢?按理說 能夠;(實際上也是能夠的,官文有介紹)
是否能夠定時執行爬蟲程序呢?按理說 能夠;(本文未介紹)
關於第一個「執行多個」的問題,在官文 Common Practices中有介紹,示例以下(仍然是在Scrapy項目外):
1 import scrapy 2 from scrapy.crawler import CrawlerProcess 3 from baidu_com import BaiduComSpider 4 from msn_com import MsnComSpider 5 6 # 建立一個CrawlerProcess對象 7 process = CrawlerProcess() # 括號中能夠添加參數 8 9 process.crawl(BaiduComSpider) 10 process.crawl(MsnComSpider) 11 process.start()
執行結果:不過,注意日誌顯示的抓取順序和代碼中相反。
方式四:CrawlerRunner
官文對CrawlerRunner有更詳細的介紹,還涉及到Twisted模塊中的Reactor、Deferred等,而孤對Twisted模塊的用法還不熟悉,只是昨天看了Deferred的參考文檔。
可是,本文的目的是使用CrawlerRunner來編寫腳本運行爬蟲程序,那麼,關於Twisted能夠稍候詳細瞭解,須要精通。
本節包括下面的程序(均爲Scrapy項目外):
-運行單個爬蟲程序
-運行多個爬蟲程序
-使用inlineCallbacks的方式運行爬蟲程序(多個)
運行單個爬蟲程序
1 from twisted.internet import reactor 2 import scrapy 3 from scrapy.crawler import CrawlerRunner 4 from scrapy.utils.log import configure_logging 5 from baidu_com import BaiduComSpider 6 7 # 必須執行下面的,不然命令行中沒有數據輸出,555, 8 configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'}) 9 10 # 建立一個CrawlerRunner對象 11 runner = CrawlerRunner() 12 13 d = runner.crawl(BaiduComSpider) # 返回一個Twisted中的Deferred對象 14 d.addBoth(lambda _: reactor.stop()) # addBoth參考Derrerred的文檔 15 reactor.run()
執行結果:獲取數據成功,,不過,第一次執行什麼也沒有輸出到命令行中,由於沒有執行configure_logging,爲什麼這樣?
運行多個爬蟲程序
1 from twisted.internet import reactor 2 import scrapy 3 from scrapy.crawler import CrawlerRunner 4 from scrapy.utils.log import configure_logging 5 from baidu_com import BaiduComSpider 6 from techmeme_com import TechmemeComSpider 7 8 configure_logging() 9 10 # 建立一個CrawlerRunner對象 11 runner = CrawlerRunner() 12 13 runner.crawl(BaiduComSpider) 14 runner.crawl(TechmemeComSpider) 15 d = runner.join() # 在多線程編程中見到過此函數,這裏是? 16 d.addBoth(lambda _: reactor.stop()) # addBoth參考Derrerred的文檔 17 reactor.run()
執行結果:獲取數據成功,不過,techmeme.com的抓取結果 沒有「一瞬間」顯示出來,而是延遲了2~3秒。
注意,其獲取網頁的順序和程序中添加的一致,固然,也多是由於延遲問題。
使用inlineCallbacks的方式運行爬蟲程序(多個)
須要懂Twisted的Dererred才能理解的!孤目前懂了10%吧?程序以下:
1 from twisted.internet import reactor, defer 2 3 from scrapy.crawler import CrawlerRunner 4 from scrapy.utils.log import configure_logging 5 6 from baidu_com import BaiduComSpider 7 from techmeme_com import TechmemeComSpider 8 9 configure_logging() 10 11 # 建立一個CrawlerRunner對象 12 runner = CrawlerRunner() 13 14 # 關鍵點來了! 15 @defer.inlineCallbacks 16 def crawl(): 17 yield runner.crawl(BaiduComSpider) 18 yield runner.crawl(TechmemeComSpider) 19 reactor.stop() 20 21 # 調用crawl() 22 crawl() 23 24 reactor.run()
執行結果:執行成功(就不展現截圖了,和前面一個程序的結果同樣)!
總結
經過本文,孤對運行爬蟲程序的方式有了更全面的瞭解了,讀者您呢?
不過會有些不足,那就是對Twisted的reactor、Deferred不瞭解,而且本身對Python的裝飾器使用沒有達到精通級別,因此,看到裝飾器會有些發怵!
本文沒有 定時執行爬蟲程序 的方法,由於水平不足,不過,既然都能在程序執行了,那麼,離完成 定時執行爬蟲程序 的目標還遠嗎?
沒有寫 分佈式爬蟲 的問題,孤本身懂了再寫唄!
在看Twisted的文檔時會遇到不少「新東西」,這就是困難了,心中對本身的指望應該是——讀一遍就能夠了,本身很聰明,但是呢?本身不過是個不如想象中聰明的普通人,一遍,是遠遠不夠的,要不少遍!同時結合多練習,這也是孤最近學習東西時發現的一個問題——把本身的學習能力「想象」的太厲害了,而當顯示出現差距時,本身就會感受挫折,產生負面情緒。不過,如今認識到這一點了,能更好地理解本身了,因此,不會以爲學不會,只是以爲一遍學不會而已,不會再對本身這我的產生懷疑。
對了,下面是Twisted的一些連接(學習Twisted還須要懂的異步、同步、阻塞、非阻塞IO,更別說Python的裝飾器、協程等基礎知識和最新的async/awati關鍵字的使用了):
P.S.又寫了一篇,感受本身棒棒噠!幸好吃了那個小蛋糕!~今天的筆記本電量消耗好快啊(5個半小時),剩餘36%了!並且沒帶充電器!~