gpt4 book ai didi

django - 使用 Channels 实现 WebSockets 后,Scrapy Spider 无法在 Django 上工作(无法从异步上下文调用它)

转载 作者:行者123 更新时间:2023-12-04 03:57:06 25 4
gpt4 key购买 nike

我正在提出一个新问题,因为我在 Django 应用程序中遇到了 Scrapy 和 Channels 问题,如果有人能指导我朝着正确的方向发展,我将不胜感激。
我使用 channel 的原因是因为我想从 Scrapyd API 实时检索抓取状态,而不必一直使用 setIntervals,因为这应该成为可能被许多人使用的 SaaS 服务用户。
如果我运行,我已经正确实现了 channel :

python manage.py runserver
我可以正确地看到系统现在正在使用 ASGI:
System check identified no issues (0 silenced).
September 01, 2020 - 15:12:33
Django version 3.0.7, using settings 'seotoolkit.settings'
Starting ASGI/Channels version 2.4.0 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
此外,客户端和服务器通过 WebSocket 正确连接:
WebSocket HANDSHAKING /crawler/22/ [127.0.0.1:50264]
connected {'type': 'websocket.connect'}
WebSocket CONNECT /crawler/22/ [127.0.0.1:50264]
到目前为止一切顺利,当我通过 Scrapyd-API 运行 scrapy 时出现问题
2020-09-01 15:31:25 [scrapy.core.scraper] ERROR: Error processing {'url': 'https://www.example.com'}
raceback (most recent call last):
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/twisted/internet/defer.py", line 654, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/scrapy/utils/defer.py", line 157, in f
return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
File "/private/var/folders/qz/ytk7wml54zd6rssxygt512hc0000gn/T/crawler-1597767314-spxv81dy.egg/webspider/pipelines.py", line 67, in process_item
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/db/models/query.py", line 411, in get
num = len(clone)
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/db/models/query.py", line 258, in __len__
self._fetch_all()
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/db/models/query.py", line 1261, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/db/models/query.py", line 57, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1150, in execute_sql
cursor = self.connection.cursor()
File "/Users/Andrea/anaconda3/envs/DjangoScrape/lib/python3.6/site-packages/django/utils/asyncio.py", line 24, in inner
raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
我认为错误消息很清楚:您不能从异步上下文调用它 - 使用线程或 sync_to_async = 我猜通过启用 ASGI 会与 Scrapy 库发生冲突,导致其无法正常工作。
不幸的是,我无法理解这背后的原因,也不应该像建议的那样使用“线程或sync_to_async”。
请注意,WebSockets 仅用于检查抓取状态,没有其他用途。
任何人都可以尝试向我解释这种不兼容背后的原因,并就如何克服这一障碍给我一些提示吗?我花了很多时间寻找答案,但找不到任何答案。
非常感谢。

最佳答案

您只需转到 pipelines.py 文件即可解决此错误。进口 sync_to_async 来自 asgiref.sync .

from asgiref.sync import sync_to_async
导入后 sync_to_async ,您需要将其用作用于将数据存储到数据库的函数的装饰器。
例如
from itemadapter import ItemAdapter
from crawler.models import Movie
from asgiref.sync import sync_to_async


class MovieSpiderPipeline:
@sync_to_async
def process_item(self, item, spider):
movie = Movie(**item)
movie.save()
return item

关于django - 使用 Channels 实现 WebSockets 后,Scrapy Spider 无法在 Django 上工作(无法从异步上下文调用它),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63690947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com