標籤:
最近實驗室的項目中有一個需求是這樣的,需要爬取若干個(數目不小)網站發布的文章中繼資料(標題、時間、本文等)。問題是這些網站都很老舊和小眾,當然也不可能遵守 Microdata這類標準。這時候所有網頁共用一套預設規則無法保證正確抓取到資訊,而每個網頁寫一份spider代碼也不切實際。
這時候,我迫切地希望能有一個架構可以通過唯寫一份spider代碼和維護多個網站的爬取規則,就能自動抓取這些網站的資訊,很慶幸 Scrapy 可以做到這點。鑒於國內外關於這方面資料太少,所以我將這段時間來的經驗和代碼分享成了本文。
為了講清楚這件事,我分成了三篇文章來敘述:
- 編程方式下運行 Scrapy spider
- 使用Scrapy定製可動態配置的爬蟲
- 使用Redis和SQLAlchemy對Scrapy Item去重並儲存
本篇文章主要介紹如何使用編程的方式運行Scrapy爬蟲。
在開始本文之前,你需要對 Scrapy 有所熟悉,知道 Items、Spider、Pipline、Selector 的概念。如果你是 Scrapy 新手,想瞭解如何用Scrapy開始爬取一個網站,推薦你先看看官方的教程。
運行一個Scrapy爬蟲可以通過命令列的方式(scrapy runspider myspider.py)啟動,也可以使用核心API通過編程的方式啟動。為了獲得更高的定製性和靈活性,我們主要使用後者的方式。
我們使用官方教程中的 Dmoz 例子來協助我們理解使用編程方式啟動spider。我們的 spider 檔案dmoz_spider.py 長這個樣子:
| 12345678910111213141516171819202122 |
import scrapy class DmozItem(scrapy.Item): title = scrapy.Field() link = scrapy.Field() desc = scrapy.Field() class DmozSpider(scrapy.Spider): name = "dmoz" allowed_domains = ["dmoz.org"] start_urls = [ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" ] def parse(self, response): for sel in response.xpath(‘//ul/li‘): item = DmozItem() item[‘title‘] = sel.xpath(‘a/text()‘).extract() item[‘link‘] = sel.xpath(‘a/@href‘).extract() item[‘desc‘] = sel.xpath(‘text()‘).extract() yield item |
接下來我們需要寫一個指令碼run.py,來運行DmozSpider:
| 123456789101112131415161718192021222324252627 |
from dmoz_spider import DmozSpider # scrapy apifrom scrapy import signals, logfrom twisted.internet import reactorfrom scrapy.crawler import Crawlerfrom scrapy.settings import Settings def spider_closing(spider): """Activates on spider closed signal""" log.msg("Closing reactor", level=log.INFO) reactor.stop() log.start(loglevel=log.DEBUG)settings = Settings() # crawl responsiblysettings.set("USER_AGENT", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36")crawler = Crawler(settings) # stop reactor when spider closescrawler.signals.connect(spider_closing, signal=signals.spider_closed) crawler.configure()crawler.crawl(DmozSpider())crawler.start()reactor.run() |
然後運行python run.py就啟動了我們的爬蟲了,但是由於我們這裡沒有對爬下來的結果進行任何的儲存操作,所以看不到結果。你可以寫一個 item pipline 用來將資料存放區到資料庫,使用settings.set介面將這個 pipline 配置到ITEMS_PIPLINE,我們將在第三篇文章中具體講解這部分內容。下一篇部落格將會介紹如何通過維護多個網站的爬取規則來抓取各個網站的資料。
你可以在 GitHub 上看到本文的完整項目。
註:本文使用的 Scrapy 版本是 0.24,GitHub 上的master分支已支援 Scrapy 1.0
本系列的三篇文章
- Python爬蟲架構Scrapy教程(1)——入門
- Python爬蟲架構Scrapy教程(2)—動態可配置
- Python爬蟲架構Scrapy教程(3)—使用Redis和SQLAlchemy對Scrapy Item去重並儲存
參考資料
- Running scrapy spider programmatically
Python爬蟲架構Scrapy教程(1)—入門