摘要:根據Excel文件配置運行多個爬蟲python
不少時候,咱們都須要爲每個單獨的網站編寫一個爬蟲,但有一些狀況是你要爬取的幾個網站的惟一不一樣之處在於Xpath表達式不一樣,此時要分別爲每個網站編寫一個爬蟲就顯得徒勞了,其實能夠只使用一個spider就爬取這些類似的網站。git
首先建立一個名爲generic的工程和一個名爲fromcsv的spider:github
scrapy startproject generic
cd generic
scrapy genspider fromcsv example.com
而後建立一個csv文件,在文件中填充如下信息:dom
使用Python的csv庫來驗證一下scrapy
$ python >>> import csv >>> with open("todo.csv", "rU") as f: reader = csv.DictReader(f) for line in reader: print line
輸出以下:ide
注意:todo.csv文件的第一行會自動做爲字典的key函數
如今讀取todo.csv文件中的URL和Xpath表達式來運行spider,因爲咱們並不能提早知道URL,因此要從spider中移除start_urls和allowed_domains部分,使用start_requests()方法,對於csv文件中的每一行都產生一個Request對象,而且將字段名和Xpath表達式放入參數request.mate中,傳遞到parse函數,而後永Item和ItemLoader來填充item的字段網站
import csv import scrapy from scrapy.http import Request from scrapy.loader import ItemLoader from scrapy.item import Item, Field class FromcsvSpider(scrapy.Spider): name = "fromcsv" def start_requests(self): with open("todo.csv", "rU") as f: reader = csv.DictReader(f) for line in reader: request = Request(line.pop('url')) #從字典中彈出了key爲url的元素 request.meta['fields'] = line yield request def parse(self, response): item = Item() # 在本工程中並無定義items.py文件 l = ItemLoader(item=item, response=response) for name, xpath in response.meta['fields'].iteritems(): if xpath: item.fields[name] = Field() # 動態建立一個item l.add_xpath(name, xpath) return l.load_item()
fromcsv.py源文件代碼地址:編碼
https://github.com/Kylinlin/scrapybook/blob/master/ch05%2Fgeneric%2Fgeneric%2Fspiders%2Ffromcsv.pyurl
運行spider:scrapy crawl fromcsv
因爲上面的源碼中硬編碼了todo.csv文件名,一旦文件名發生了變更就須要修改源代碼,這並非一個好的設計,其實Scrapy使用了一個簡便的方式(使用 -a)能夠從命令行向spider傳送參數,例如:-a variable=value,那麼spider就能夠在源代碼中的self.variable來獲取value。爲了檢查變量名並提供默認值,就使用Python的方法getarrt(self, ‘variable’, ‘default’),因此上面的with語句能夠修改成:
with open(getarrt(self, 「file」, 「todo.csv」), 「rU」) as f:
而後在運行spider時經過-a參數來指定csv文件(若是沒有使用-a參數,就默認使用todo.csv文件):
scrapy crawl fromcsv –a file=todo.csv