【问题标题】:How to run ScrapyRT over Heroku with custom settings?如何使用自定义设置在 Heroku 上运行 ScrapyRT?
【发布时间】:2022-06-23 01:19:13
【问题描述】:

我有一个 Scrapy 项目,在它之上,我有 ScrapyRT 来创建一个 API。首先,我使用默认设置和 Procfile 在 Heroku 中部署应用程序,如下所示:

web: scrapyrt -i 0.0.0.0 -p $PORT

到目前为止一切都很好,它按预期运行。

Scrapy 项目有一个管道,可以将抓取的项目发送到 mongo 数据库。这也很好用。

现在,由于我已经将抓取的数据保存到数据库中,我的目的是创建一个额外的资源来处理 get 请求,以便 ScrapyRT 检查数据库中的项目是否之前被废弃,并返回它而不是运行蜘蛛。根据 ScrapyRT 的文档,为了添加新资源,我需要通过命令行(Windows 中的 PowerShell)传递自定义设置,如下所示:

scrapyrt -S nist_scraper.scrapyrt.settings

其中nist_scraper是项目名称,scrapyrt是项目内部的子目录,settings是设置所在的python文件的名称。

# nist_scraper/scrapyrt/settings.py

RESOURCES = {
    'crawl.json': 'nist_scraper.scrapyrt.resources.CheckDatabaseBeforeCrawlResource',
}
# resourse.py
# custom

import os
import json

from pymongo import MongoClient
from dotenv import load_dotenv
load_dotenv()

from scrapyrt.resources import CrawlResource



class CheckDatabaseBeforeCrawlResource(CrawlResource):

    def render_GET(self, request, **kwargs):

        # Get the url parameters
        api_params = dict(
            (name.decode('utf-8'), value[0].decode('utf-8'))
            for name, value in request.args.items()
        )
            
        try:
            cas = json.loads(api_params["crawl_args"])["cas"]
            collection_name = "substances"
            client = MongoClient(os.environ.get("MONGO_URI"))
            db = client[os.environ.get("MONGO_DB")]
        except:
            return super(CheckDatabaseBeforeCrawlResource, self).render_GET(
                request, **kwargs)

        substance = db[collection_name].find_one({"cas":cas}, {"_id":0})
        if substance:
            response = {
            "status": "ok",
            "items": [substance],
            }                #<== Here is supposed to be the metadata but is gone on purpose

            return response
        
        return super(CheckDatabaseBeforeCrawlResource, self).render_GET(
        request, **kwargs)

再次,在本地,一旦我发送了获取请求

{{BASE_URL}}crawl.json?spider_name=webbook_nist&amp;start_requests=true&amp;crawl_args={"cas":"74828"}

我得到了想要的行为,资源从数据库而不是从 Scrapy 项目中的蜘蛛发送项目。我知道该项目来自数据库,因为我修改了 ScrapyRT 返回的响应并删除了所有元数据。

但是,这里有问题。我将同一个本地项目更新到 Heroku 以覆盖开头提到的原始项目,该项目运行良好并将 Procfile 更改为:

web: scrapyrt -S nist_scraper.scrapyrt.settings -i 0.0.0.0 -p $PORT

但是当我发送相同的 get 请求时,ScrapyRT 调用蜘蛛并且不检查该项目是否在数据库中。说清楚点,数据库是一样的,项目确实记录在那个数据库里。发送的响应包含我从自定义资源中删除的元数据。

我对 Heroku 和 ScrapyRT 都不精通,但我假设问题是 Heroku 在启动 API 时没有添加我的自定义设置,因此 ScrapyRT 模块正在运行其默认设置,这些设置总是使用蜘蛛程序报废网站。

该项目正在这里:https://nist-scrapyrt.herokuapp.com/crawl.json?spider_name=webbook_nist&start_requests=true&crawl_args={%22cas%22:%227732185%22}

这里有一个 GitHub 代码库:https://github.com/oscarcontrerasnavas/nist-webbook-scrapyrt-spider

据我所知,如果我不通过命令行参数添加自定义设置,scrapy.cfg 的默认设置将被 ScrapyRT 的默认设置覆盖。

我想要与本地环境相同的行为,但在 Heroku 上。我不想每次都运行蜘蛛,因为我知道从数据库中提取信息不那么“昂贵”。

有什么建议吗?

【问题讨论】:

    标签: heroku command-line scrapy settings


    【解决方案1】:

    这个问题中显示的实现是正确的,Heroku 上的环境变量有一个错字。如果您对如何自己做有疑问,可以发表评论。

    【讨论】:

      猜你喜欢
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 1970-01-01
      • 2012-12-26
      • 2013-05-01
      • 2021-06-17
      • 2015-06-29
      相关资源
      最近更新 更多