如何使用scrapy抓取多个域

如何使用scrapy抓取多个域,scrapy,scrapyd,scrapy-spider,Scrapy,Scrapyd,Scrapy Spider,我有一个项目,其中我必须抓取大量不同的网站。所有这些站点爬行都可以使用同一个爬行器,因为我不需要从它的主体页面中提取项目。我认为的方法是在spider文件中参数化要爬网的域,并调用scrapy crawl命令作为参数传递域和启动URL,这样我就可以避免为每个站点生成一个spider(站点列表将随着时间的推移而增加)。我们的想法是将其部署到运行scrapyd的服务器上,因此我遇到了几个问题: 这是我能采取的最好办法吗 如果是这样的话,如果我使用不同的参数多次调度同一个爬行器,是否会出现并发问题

我有一个项目,其中我必须抓取大量不同的网站。所有这些站点爬行都可以使用同一个爬行器,因为我不需要从它的主体页面中提取项目。我认为的方法是在spider文件中参数化要爬网的域,并调用scrapy crawl命令作为参数传递域和启动URL,这样我就可以避免为每个站点生成一个spider(站点列表将随着时间的推移而增加)。我们的想法是将其部署到运行scrapyd的服务器上,因此我遇到了几个问题:

  • 这是我能采取的最好办法吗
  • 如果是这样的话,如果我使用不同的参数多次调度同一个爬行器,是否会出现并发问题
  • 如果这不是最好的方法,最好是每个站点创建一个spider。。。我必须经常更新这个项目。项目更新是否会影响正在运行的spider

    • 卡盘设计

      有两种方法可以构建域spider

    • 将URL列表作为参数发送到单个spider
    • 使用不同的起始url作为参数运行同一个spider的多个实例
    • 第一种方法是最直接、最容易测试的(您可以使用scrapy crawl运行),在许多情况下都很好。 第二种方法不太方便使用,但更容易编写代码:

    • 将URL列表作为参数发送到单个爬行器:
      • 最小CPU占用:为所有URL启动一个进程
      • 用户友好:可作为scrapy crawl或scrapyd运行
      • 更难调试:没有域限制
    • 为每个启动url运行1个实例
      • 占用大量资源:为每个url启动1个专用进程
      • 非用户友好型:需要创建外部脚本来启动spider和馈送URL
      • 易于调试:编写代码一次运行一个域
    • 只有当您遇到编程挑战时,我才推荐第二种方法。否则,为了简单性和可伸缩性,请坚持使用选项1

      并发性

      通过按域变量添加并发请求,可以通过
      settings.py
      控制并发

      项目更新

      两种架构都只需要编写一个spider。您只能实例化爬行器一次(选项1)或每个url实例化一次(选项2)。您不需要编写多个spider


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

      为什么第一个选项是更好的选择?我看不出有什么好处。关于项目更新,我会重新制作这个问题,然后我会回答自己。我想知道,如果我在运行scrapyd服务时部署了scrapyd,在scrapyd服务下运行的scrapy Spider是否会受到影响。答案是否定的,他们继续运行,没有进一步的问题。我不能给你一个积极的投票,因为我没有足够的声誉。谢谢你的反馈。我相信,我澄清了你所有的问题。你怎么看?我不明白第二种选择是怎么可能的,因为爬虫程序使用爬行器类(而不是实例)来启动。因此,您必须为每个要爬网的域创建一个类。我知道这没有道理,但我找不到其他办法it@AlexPatchanka,爬虫程序实际使用实例(解析方法等是实例方法,而不是类方法)。另一个挑战是将多个spider实例化到单个进程中还是实例化到单个进程中。我认为您可能会混淆成员
      允许的\u域
      ,它可以在运行时(基于输入)而不是在源代码中设置。
      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)