如何使用scrapy抓取多个域名

Ber*_*lla 5 scrapy scrapyd

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

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

Fre*_*zin 6

蜘蛛设计

有两种构建域蜘蛛的方法

  1. 将 url 列表作为参数发送给单个蜘蛛
  2. 使用不同的 start_url 作为参数运行同一蜘蛛的多个实例

第一种方法是最直接且易于测试的(您可以使用 scrapy scrapy 运行),并且在许多情况下都很好。第二种方法使用起来不太方便,但更容易编写代码:

  1. 将 url 列表作为参数发送给单个蜘蛛:
    • 最小的 CPU 占用:为所有 URL 启动 1 个进程
    • 用户友好:可以作为 scrapycrapy 或 scrapyd 运行
    • 更难调试:没有域限制
  2. 为每个 start_url 运行 1 个实例
    • 大量资源占用:为每个 url 启动 1 个专用进程
    • 对用户不友好:需要创建一个外部脚本来启动蜘蛛和提要网址。
    • 更容易调试:编写代码一次运行 1 个域

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)
Run Code Online (Sandbox Code Playgroud)

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

并发性

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

项目更新

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

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