摘要:根據Excel文件配置運行多個爬蟲
很多時候,我們都需要為每一個單獨的網站編寫一個爬蟲,但有一些情況是你要爬取的幾個網站的唯一不同之處在於Xpath表達式不同,此時要分別為每一個網站編寫一個爬蟲就顯得徒勞了,其實可以只使用一個spider就爬取這些相似的網站。
首先創建一個名為generic的工程和一個名為fromcsv的spider:
scrapy startproject generic
cd generic
scrapy genspider fromcsv example.com
然后創建一個csv文件,在文件中填充以下信息:
使用Python的csv庫來驗證一下
$ python >>> import csv >>> with open("todo.csv", "rU") as f: reader = csv.DictReader(f) for line in reader: print line
輸出如下:
注意: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.py
運行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