scrapy用不同规则抓取多个网站(基于csv文件)以及向爬虫传递参数(参数可默认)
大多数情况下每个网站对应一个爬虫,但是也有很多时候需要一个爬虫抓取多个网站,而它们之间的唯一区别只是XPath表达式不同。在这种情况下,对应每个网站编写一个爬虫有些大材小用,只需一个爬虫即可解决。
首先创建一个.csv文件 ,按照下图填写一些url和XPath表达式,保存为todo.csv并放到工程的目录(也就是scrapy.cfg文件所在的目录)。
Python有一个内建的库专门处理.csv文件,需引入import csv。用下面的代码:
$ pwd /root/book/ch05/generic2 $ python >>> import csv >>> with open("todo.csv", "rU") as f: reader = csv.DictReader(f) for line in reader: print line
csv文件的第一行会被自动当做表头,其中的内容作为将要生成的字典的键。每次for循环中,文件的每一行都生成一个字典。运行上面的代码可以得到以下输出:
{'url': ' http://a.html', 'price': '//*[@id="prcIsum"]/text()', 'name': '//*[@id="itemTitle"]/text()'} {'url': ' http://b.html', 'price': '//span/strong/text()', 'name': '//h1/text()'} {'url': ' http://c.html', 'price': '', 'name': '//* [@id="product-desc"]/span/text()'}
由于不是抓取预先知道的url,而是从文件中读取url,这就需要重新实现start_request()函数。对于文件的每一行,产生一个Request并yield。然后在request.meta中保存XPath表达式以便在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')) request.meta['fields'] = line yield request
def parse(self, response): item = Item() l = ItemLoader(item=item, response=response) for name, xpath in response.meta['fields'].iteritems(): if xpath: item.fields[name] = Field() l.add_xpath(name, xpath) return l.load_item()
上面的代码可以会跟平常的代码有一些不同:
没有为整个工程生成Item
item = Item() l = ItemLoader(item=item, response=response)
用Item的成员变量fields来动态地添加字段
item.fields[name] = Field()
l.add_xpath(name, xpath)
硬编码todo.csv文件在实践中不太好。Scrapy可以在命令行中用-a来向爬虫传递参数。例如,-a variable=value,这样会设置爬虫的一个variable属性,可以在程序中用self.variable来访问。如果没有提供的话还可以使用默认参数:getattr(self, 'variable', 'default')。综上,可以把原来的打开文件的代码换成:
with open(getattr(self, "file", "todo.csv"), "rU") as f:
现在todo.csv是默认值,除非用-a选项显式地设置url源文件。如果存在另一个文件another_todo.csv,可以运行下面的命令:
$ scrapy crawl fromcsv -a file=another_todo.csv -o out.csv
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击