【发布时间】: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&start_requests=true&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 模块正在运行其默认设置,这些设置总是使用蜘蛛程序报废网站。
这里有一个 GitHub 代码库:https://github.com/oscarcontrerasnavas/nist-webbook-scrapyrt-spider
据我所知,如果我不通过命令行参数添加自定义设置,scrapy.cfg 的默认设置将被 ScrapyRT 的默认设置覆盖。
我想要与本地环境相同的行为,但在 Heroku 上。我不想每次都运行蜘蛛,因为我知道从数据库中提取信息不那么“昂贵”。
有什么建议吗?
【问题讨论】:
标签: heroku command-line scrapy settings