如何使用scrapy爬网多个域

时间:2014-07-01 16:33:38

标签: scrapy scrapyd scrapy-spider

我有一个项目,我必须抓取大量不同的网站。所有这些网站爬行都可以使用相同的蜘蛛,因为我不需要从其正文页面中提取项目。我想的方法是在蜘蛛文件中对要爬网的域进行参数化,并调用scrapy crawl命令将域和起始URL作为参数传递,这样我就可以避免为每个站点生成一个蜘蛛(站点列表会增加时间)。我的想法是将它部署到运行scrapyd的服务器上,因此有几个问题出现在我面前:

  • 这是我能采取的最佳方法吗?
  • 如果是这样,如果我多次安排使用不同参数的同一个蜘蛛,是否会出现并发问题?
  • 如果这不是最好的方法,最好每个站点创建一个蜘蛛......我将不得不经常更新项目。项目更新是否会影响正在运行的蜘蛛?

1 个答案:

答案 0 :(得分:4)

蜘蛛设计

有2种构建域蜘蛛的方法

  1. 将一个网址列表发送给单个蜘蛛作为参数
  2. 使用不同的start_url作为参数运行同一个蜘蛛的多个实例
  3. 第一种方法是最直接且易于测试(您可以使用scrapy爬行运行)并且在许多情况下都很好。 第二种方法使用起来不太方便,但编写代码更容易:

    1. 将网址列表发送给单个蜘蛛作为参数:
      • 最小CPU占用空间:为所有网址启动1个单一流程
      • 用户友好:可以作为scrapy crawl或scrapyd运行
      • 更难调试:没有域名限制
    2. 为每个start_url运行1个实例
      • 资源占用空间:为每个网址启动1个专用流程
      • 非用户友好:需要创建外部脚本来启动蜘蛛和Feed网址。
      • 更容易调试:编写代码以一次运行1个域
    3. from urlparse import urlparse
      ...
      class .....(Spider):
          def __init__(*args, *kwargs):
              ...
              self.start_urls = ....
              ...
              self.allowed_domains = map(lambda x: urlparse(x).netloc, self.start_urls)
      

      只有遇到编程挑战时,我才会推荐第二种方法。否则为了简单和可扩展性而坚持选项1

      <强>并发

      您可以通过添加CONCURRENT_REQUESTS_BY_DOMAIN变量来settings.py来控制并发。

      项目更新

      这两种架构都只需要编写1个蜘蛛。您只需将蜘蛛实例化一次(选项1)或每个URL实例化一次(选项2)。你不需要写多个蜘蛛。

      仅供参考:更新项目不会影响正在运行的蜘蛛。