【问题标题】:Getting scrapy project settings when script is outside of root directory当脚本位于根目录之外时获取scrapy项目设置
【发布时间】:2015-10-18 05:04:33
【问题描述】:

我制作了一个可以从项目根目录中的脚本成功运行的 Scrapy 蜘蛛。由于我需要从同一个脚本的不同项目中运行多个蜘蛛(这将是一个 django 应用程序根据用户的请求调用该脚本),我将脚本从其中一个项目的根目录移动到了父目录。出于某种原因,该脚本不再能够获取项目的自定义设置,以便将抓取的结果通过管道传输到数据库表中。这是我用来从脚本运行蜘蛛的 scrapy 文档中的代码:

def spiderCrawl():
   settings = get_project_settings()
   settings.set('USER_AGENT','Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)')
   process = CrawlerProcess(settings)
   process.crawl(MySpider3)
   process.start()

是否需要导入一些额外的模块才能从项目外部获取项目设置?还是需要对此代码进行一些补充?下面我还有运行蜘蛛的脚本代码,谢谢。

from ticket_city_scraper.ticket_city_scraper import *
from ticket_city_scraper.ticket_city_scraper.spiders import tc_spider
from vividseats_scraper.vividseats_scraper import *
from vividseats_scraper.vividseats_scraper.spiders import vs_spider 

tc_spider.spiderCrawl()
vs_spider.spiderCrawl()

【问题讨论】:

    标签: python django web-scraping scrapy


    【解决方案1】:

    我使用 OS 模块来解决这个问题。 您正在运行的 python 文件在一个目录中,而您的 scrapy 项目在另一个目录中。您不能简单地只导入 python 蜘蛛并在此 python 脚本上运行,因为您正在工作的当前目录没有 settings.py 文件或 scrapy.cfg。

    导入操作系统

    要显示您正在使用的当前目录,请使用以下代码:

    打印(os.getcwd())

    从这里您将要更改当前目录:

    os.chdir(\path\to\spider\folder)

    最后,告诉操作系统执行哪个命令。

    os.system('scrape_file.py')

    【讨论】:

      【解决方案2】:

      感谢这里已经提供的一些答案,我意识到scrapy 实际上并没有导入 settings.py 文件。我就是这样解决的。

      TLDR:确保将“SCRAPY_SETTINGS_MODULE”变量设置为实际的 settings.py 文件。我在 Scraper 的 __init__() 函数中执行此操作。

      考虑一个具有以下结构的项目。

      my_project/
          main.py                 # Where we are running scrapy from
          scraper/
              run_scraper.py               #Call from main goes here
              scrapy.cfg                   # deploy configuration file
              scraper/                     # project's Python module, you'll import your code from here
                  __init__.py
                  items.py                 # project items definition file
                  pipelines.py             # project pipelines file
                  settings.py              # project settings file
                  spiders/                 # a directory where you'll later put your spiders
                      __init__.py
                      quotes_spider.py     # Contains the QuotesSpider class
      

      基本上,命令 scrapy startproject scraper 在 my_project 文件夹中执行,我在外层刮板文件夹中添加了一个 run_scraper.py 文件,在我的根文件夹中添加了一个 main.py 文件,在蜘蛛文件夹中添加了 quotes_spider.py

      我的主文件:

      from scraper.run_scraper import Scraper
      scraper = Scraper()
      scraper.run_spiders()
      

      我的run_scraper.py 文件:

      from scraper.scraper.spiders.quotes_spider import QuotesSpider
      from scrapy.crawler import CrawlerProcess
      from scrapy.utils.project import get_project_settings
      import os
      
      
      class Scraper:
          def __init__(self):
              settings_file_path = 'scraper.scraper.settings' # The path seen from root, ie. from main.py
              os.environ.setdefault('SCRAPY_SETTINGS_MODULE', settings_file_path)
              self.process = CrawlerProcess(get_project_settings())
              self.spider = QuotesSpider # The spider you want to crawl
      
          def run_spiders(self):
              self.process.crawl(self.spider)
              self.process.start()  # the script will block here until the crawling is finished
      

      另外,请注意设置可能需要查看,因为路径需要根据根文件夹(my_project,而不是 scraper)。 所以就我而言:

      SPIDER_MODULES = ['scraper.scraper.spiders']
      NEWSPIDER_MODULE = 'scraper.scraper.spiders'
      

      然后重复你拥有的所有设置变量!

      【讨论】:

      • 谢谢,你救了我的命,我不得不修改 settings.py,就像最后一个注释解释的那样。
      【解决方案3】:

      我已经用这段代码解决了这个问题:

      from scrapy.settings import Settings
      
      settings = Settings()
      
      settings_module_path = os.environ.get('SCRAPY_ENV', 'project.settings.dev')   
      settings.setmodule(settings_module_path, priority='project')
      
      print(settings.get('BASE_URL'))
      

      【讨论】:

        【解决方案4】:

        应该可以了,你能分享你的scrapy日志文件吗

        编辑: 你的方法行不通 因为...当您执行脚本时..它会在

        中查找您的默认设置
        1. 如果您已设置环境变量 ENVVAR
        2. 如果您在执行脚本的当前目录中有 scrapy.cfg 文件,并且如果该文件指向有效的 settings.py 目录,它将加载这些设置...李>
        3. 否则它将使用 scrapy 提供的 vanilla 设置运行(您的情况)

        解决方案 1 在目录(外部文件夹)内创建一个 cfg 文件并为其提供有效 settings.py 文件的路径

        解决方案 2 制作你的父目录包,这样就不需要绝对路径,你可以使用相对路径

        即 python -m cron.project1

        解决方案 3

        你也可以试试

        让它在它所在的地方,在项目目录中......它正在工作的地方......

        创建一个 sh 文件...

        • 第 1 行:Cd 到第一个项目位置(根目录)
        • 第 2 行:Python script1.py
        • 第 3 行。Cd 到第二个项目位置
        • 第 4 行:python script2.py

        现在你可以在 django 请求时通过这个 sh 文件执行爬虫

        【讨论】:

        • 在哪里可以找到日志文件?另外,我之前发布了一个关于运行 bash 脚本以按照您的建议运行蜘蛛的问题,但有人建议只在 celery 任务中运行蜘蛛。
        • log.start(logfile='my.log') ...就在您开始抓取之前 - 它会将日志保存在 my.log 文件中。
        • 您能否指定您的解决方案 1 的外观/应该是什么样子,或者提供一个链接来说明该解决方案的工作原理?
        • 基本上,将cfg文件复制到您要运行此项目的目录,然后更改scrapy.cfg中的路径 default = ..project.settings
        • 然后在您的 setttings.py 文件中更改相对于当前文件夹路径的所有路径,即更改 SPIDER_MODULES、SPIDER_MIDDLEWARES、ITEM_PIPELINES、出口商...等的路径
        【解决方案5】:

        这可能会发生,因为您不再“在”scrapy 项目“内部”,因此它不知道如何使用 get_project_settings() 获取设置。

        您也可以将设置指定为字典,例如此处:

        http://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script

        【讨论】:

        • 我不确定如何使用字典来指定项目之外的设置。你能用一个代码示例澄清一下吗?顺便说一句,我尝试的另一种方法基本上是将脚本放在项目根目录中,然后从脚本中的更高目录中的另一个脚本调用该函数(因此这个更高的脚本可以调用其他项目的脚本)。但这似乎不起作用,如果听起来令人困惑,请见谅。
        猜你喜欢
        • 2018-05-13
        • 1970-01-01
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多