当脚本在根目录之外时获取scrapy项目设置

时间:2015-07-27 20:36:18

标签: python django web-scraping scrapy

我制作了一个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()

5 个答案:

答案 0 :(得分:8)

感谢此处已经提供的一些答案,我意识到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

基本上是命令 我在my_project文件夹中执行了scrapy startproject scraper,我在外部scraper文件夹中添加了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'

并重复您拥有的所有设置变量!

答案 1 :(得分:4)

它应该可以,你可以共享你的scrapy日志文件

修改 你的方法不会奏效 因为...当你执行脚本时......它将在

中查找你的默认设置
  1. 如果您已设置环境变量ENVVAR
  2. 如果您在执行脚本的目录中有scrapy.cfg文件,并且该文件指向有效的 settings.py 目录,则会加载这些设置...
  3. 否则它将以scrapy(您的情况)提供的vanilla设置运行
  4. 解决方案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文件执行蜘蛛

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

我使用此代码来解决问题:

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 :(得分:0)

我使用OS模块来解决此问题。 您正在运行的python文件位于一个目录中,而scrapy项目位于另一个目录中。您不能仅仅导入python spider并在此python脚本上运行,因为您正在使用的当前目录没有settings.py文件或scrapy.cfg。

导入操作系统

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

打印(os.getcwd())

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

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

最后,告诉os要执行哪个命令。

os.system('scrape_file.py')