Scrapy方法来抓取多个URL

时间:2012-08-28 13:47:50

标签: python scrapy

我有一个项目,需要大量的数据抓取才能完成。

我一直在关注Scrapy,到目前为止我对此印象非常深刻,但我正在寻找最佳方法来做到以下几点:

1)我想抓取多个URL并为每个要传输的URL传入相同的变量,例如,假设我想要从Bing,Google和Yahoo返回关键字“python”的最高结果。

我想要抓取http://www.google.co.uk/q=pythonhttp://www.yahoo.com?q=pythonhttp://www.bing.com/?q=python(不是实际的网址,但你明白了)

我找不到使用关键字指定动态URL的方法,我能想到的唯一选择是在PHP或其他构建URL的文件中生成文件,并指定scrapy来抓取URL中的链接。 / p>

2)显然每个搜索引擎都有自己的标记,所以我需要区分每个结果,找到相应的XPath来提取相关数据

3)最后,我想将已删除项目的结果写入数据库(可能是redis),但只有当所有3个网址都已完成抓取时,基本上我才想从3中建立一个“配置文件”搜索引擎并将输出的结果保存在一个事务中。

如果有人对这些观点有任何想法,我将非常感激。

谢谢

3 个答案:

答案 0 :(得分:3)

1)在BaseSpider中,有一个__init__方法可以在子类中重写。这是设置start_urls和allowed_domains变量的声明的地方。如果您在运行蜘蛛之前记住了网址列表,那么您可以在此处动态插入它们。

例如,在我构建的一些蜘蛛中,我从MongoDB中提取了预先格式化的URL组,并在一次批量插入时将它们插入到start_urls列表中。

2)这可能有点棘手,但您可以通过查看响应对象(response.url)轻松查看已爬网的URL。您应该能够检查网址是否包含“google”,“bing”或“yahoo”,然后将预先指定的选择器用于该类型的网址。

3)我不太确定#3是可能的,或者至少没有一点困难。据我所知,start_urls列表中的url没有按顺序爬行,它们各自独立地进入管道。我不确定如果没有一些严重的核心黑客攻击,您将能够收集一组响应对象并将它们一起传递到管道中。

但是,您可能会考虑暂时将数据序列化到磁盘,然后将数据批量保存到数据库中。我构建的其中一个抓取工具接收的URL数量大约为10000。我将URL(和收集的数据)存储在BSON中,而不是将其插入到MongoDB中,而不是将10000个单项数据库插入。

答案 1 :(得分:1)

我会使用机械化。

import mechanize
br = mechanize.Browser()
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
br.set_handle_robots(False)
response = br.open('https://www.google.ca/search?q=python')
links = list(br.links())

为您提供所有链接。或者你可以按类筛选出来:

links = [aLink for aLink in br.links()if ('class','l') in aLink.attrs]

答案 2 :(得分:0)

您可以使用'-a'开关为蜘蛛指定一个键值对,这可能表示特定的搜索词

scrapy crawl <spider_name> -a search_word=python