【问题标题】:Scrapy - How can I load the project level settings.py while using a script to start the spiderScrapy - 如何在使用脚本启动蜘蛛时加载项目级别的 settings.py
【发布时间】:2018-10-31 09:21:58
【问题描述】:

我正在尝试实现一个使用脚本启动的爬虫蜘蛛,如下所示。

from scrapy.crawler import CrawlerRunner 
from scrapy_app.scrapy_app.spiders.generic import GenericSpider
....

class MyProcess(object):

    def start_my_process(self, _config, _req_obj, site_urls):
        runner = CrawlerRunner()       
        runner.crawl(GenericSpider, 
                config=_config, 
                reqObj=_req_obj,
                urls=site_urls)
        deferred = runner.join()
        deferred.addBoth(lambda _: reactor.stop())
        reactor.run()

    ....

因此,使用 CrawlerRunner,在执行爬虫时不会收到项目级别的 settings.py 配置。 Generic spider 接受三个参数,其中一个是起始 url 列表。

除了在蜘蛛内部设置 custom_settings 之外,我们如何将 settings.py 加载到 CrawlerRunner 进程中?

【问题讨论】:

  • @amrit 正如我所提到的,我将蜘蛛作为脚本运行,而不是使用 scrapy crawl 。您共享的链接将在您使用 scrapy 命令运行时进行设置。

标签: python scrapy scrapy-spider


【解决方案1】:

即使我的情况与您的情况并非 100% 相同,我也会尽力回答这个问题,但是,我遇到了类似的问题。

典型的scrapy项目结构如下:

scrapy.cfg
myproject/
    __init__.py
    items.py
    middlewares.py
    pipelines.py
    settings.py
    spiders/
        __init__.py
        spider1.py
        spider2.py
        ...

包含scrapy.cfg文件的目录被认为是项目的根目录。

在该文件中,您将看到如下内容:

[settings]
default: your_project.settings

[deploy]
...

在运行调用蜘蛛以使用特定设置运行的主脚本时,您应该将main.py 脚本与scrapy.cfg 文件放在同一目录中。

现在从main.py 开始,您的代码将不得不创建一个 CrawlerProcessCrawlerRunner 实例来运行蜘蛛,其中任何一个都可以使用设置对象进行实例化或像这样的字典:

process = CrawlerProcess(settings={
    'FEED_FORMAT': 'json',
    'FEED_URI': 'items.json'
}) 

---------------------------------------

from scrapy.utils.project import get_project_settings

process = CrawlerProcess(get_project_settings())

dict 场景可行,但很麻烦,所以 get_project_settings() 调用可能更有趣,我将对此进行扩展。

我有一个大型 scrapy 项目,其中包含多个共享大量类似设置的蜘蛛。所以我有一个 global_settings.py 文件,然后是每个蜘蛛中包含的特定设置。由于有大量共享设置,我喜欢将所有内容保持在一个文件中的想法,而不是复制和粘贴代码。

经过大量研究,我发现最简单的方法是使用 get_project_settings() 函数实例化 CrawlerProcess/Runner 对象,关键是 get_project_settings 使用 scrapy.cfg[settings] 下的 default 值来查找项目特定设置.

因此,当您调用 get_project_settings()。

我还要补充一点,如果你有多个scrapy项目的多个设置文件,并且你想共享根目录,你可以将它们添加到scrapy.cfg,另外像这样:

[settings]
default = your_project.settings
project1 = myproject1.settings
project2 = myproject2.settings

将所有这些设置添加到根目录配置文件将允许您在脚本中随意切换设置。

正如我之前所说,您对 get_project_settings() 的开箱即用调用将从 scrapy.cfg 文件(your_project.settings),但是,如果您想更改用于在同一进程中运行的下一个蜘蛛的设置,您可以修改为要启动的蜘蛛加载的设置。

这有点棘手和“hackey”,但它对我有用......

在第一次调用 get_project_settings() 后,将设置一个名为 SCRAPY_SETTINGS_MODULE 的环境变量。此环境变量值将设置为您在 scrapy.cfg 文件中的 default 值。要更改用于在创建的流程实例 (CrawlerRunner/Process --> process.crawl('next_spider_to_start')) 中运行的后续爬虫的设置,需要操作此变量。

这是在之前用 get_project_settings() 实例化的当前流程实例上设置新设置模块时应该做的:

import os    

# Clear the old settings module
del os.environ['SCRAPY_SETTINGS_MODULE']

# Set the project environment variable (new set of settings), this should be a value in your scrapy.cfg
os.environ['SCRAPY_PROJECT'] = 'project2'

# Call get_project_settings again and set to process object
process.settings = get_project_settings()

# Run the next crawler with the updated settings module
process.crawl('next_spider_to_start')

get_project_settings() 刚刚将您的爬虫进程实例的当前进程设置(Twisted Reactor)更新为 myproject2.settings

这一切都可以通过一个主脚本来完成,以操纵蜘蛛及其设置。就像我之前说的,我发现只拥有一个包含所有共性的全局设置文件,然后在蜘蛛本身中设置蜘蛛特定设置更容易。这通常更清楚。

Scrapy 文档有点粗糙,希望对某人有所帮助...

【讨论】:

  • 感谢 Chris Guarino 的详细解释。这说明您遇到了这种情况并努力寻找解决方案。 :) 不知何故,我以不同的方式解决了这个问题,但因为我只有一个蜘蛛并且main.py 在scrapy 项目之外,即在scapry.cfg 文件位置之外。下面的行代码解决了我的问题settings_file_path = 'scrapy_app.scrapy_app.settings' #settings path from this py file os.environ.setdefault('SCRAPY_SETTINGS_MODULE', settings_file_path) self.runner = CrawlerRunner(get_project_settings()) Cheers!
  • @sadiqmc 解决方案是正确且合法的。 Scrapy 还可以理解并且可以通过一些环境变量进行配置,例如 SCRAPY_SETTINGS_MODULE / SCRAPY_PROJECT / SCRAPY_PYTHON_SHELL
猜你喜欢
  • 2020-07-24
  • 2015-11-13
  • 2013-08-05
  • 2017-07-09
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
  • 2016-09-27
  • 2014-09-24
相关资源
最近更新 更多