python - 使用 Google Cloud Functions 时带有 scrapy 的 ReactorNotRestartable
问题描述
我正在尝试使用 Google Cloud Functions 发送多个抓取请求。但是,我似乎得到了ReactorNotRestartable
错误。从 StackOverflow 上的其他帖子,例如这个,我了解到这是因为无法重新启动反应器,特别是在执行循环时。
解决这个问题的方法是将start()
外部放在 for 循环中。但是,对于 Cloud Functions,这是不可能的,因为每个请求在技术上都应该是独立的。
是否CrawlerProcess
使用 Cloud Functions 以某种方式缓存?如果是这样,我们如何才能消除这种行为。
例如,我尝试将导入和初始化过程放在一个函数内部,而不是外部,以防止导入缓存,但这不起作用:
# main.py
def run_single_crawl(data, context):
from scrapy.crawler import CrawlerProcess
process = CrawlerProcess()
process.crawl(MySpider)
process.start()
解决方案
默认情况下,scrapy
Cloud Functions 的异步特性不能很好地工作,因为我们需要一种阻止爬取的方法,以防止函数提前返回并在进程终止之前终止实例。
相反,我们可以使用scrapydo
以阻塞方式运行您现有的蜘蛛:
requirements.txt
:
scrapydo
main.py
:
import scrapy
import scrapydo
scrapydo.setup()
class MyItem(scrapy.Item):
url = scrapy.Field()
class MySpider(scrapy.Spider):
name = "example.com"
allowed_domains = ["example.com"]
start_urls = ["http://example.com/"]
def parse(self, response):
yield MyItem(url=response.url)
def run_single_crawl(data, context):
results = scrapydo.run_spider(MySpider)
这也显示了一个简单的示例,说明如何scrapy.Item
从蜘蛛获取一个或多个并从爬虫中收集结果,如果不使用scrapydo
.
另外:确保您为您的项目启用了计费。默认情况下,Cloud Functions 无法发出出站请求,爬虫会成功,但不会返回任何结果。
推荐阅读
- c++ - 使用 at() 访问 std::map 元素是否比 operator[] 慢?
- javascript - 如何将 foreach 变量从 laravel 刀片传递到 javascript?
- discord.js - discord.js 打开和关闭 setInterval()
- python - AttributeError:“ChessBoard”对象没有属性“网格”
- r - 以有效的方式处理数据(库存数据)
- ios - SwiftUI - Google AdMob 插页式广告未显示在 onAppear 中
- sass - Less 中是否有 Sass 风格的映射键功能?
- python - 如何使用 sqlalchemy 计算平均数?
- yaml - CloudFormation YAML 状态机:无法识别令牌的 INVALID_JSON_DESCRIPTION
- python - 如何从数组中正确提取 PNG 格式的标记掩码?