Scrapy应用程序,但问题实际上是关于Python语言 - 专家可以在不知道框架的情况下立即回答这个问题。
我有一个名为CrawlWorker
的课程,知道如何与所谓的“蜘蛛”交谈 - 安排他们的爬行,并管理他们的生命周期。
TwistedRabbitClient
有一个CrawlWorker
。客户端只知道如何与队列通信并将消息传递给工作人员 - 它通过使用下面的工作方法connect_to_scrape
异步地从工作人员完成工作,以连接到正在运行的蜘蛛发出的信号: / p>
def connect_to_scrape(self, callback):
self._connect_to_signal(callback, signals.item_scraped)
def _connect_to_signal(self, callback, signal):
if signal is signals.item_scraped:
def _callback(item, response, sender, signal, spider):
scrape_config = response.meta['scrape_config']
delivery_tag = scrape_config.delivery_tag
callback(item.to_dict(), delivery_tag)
else:
_callback = callback
dispatcher.connect(_callback, signal=signal)
因此,工作人员为Rabbit客户端提供了一层“工作反序列化”,他不了解蜘蛛,响应,发件人,信号,项目(任何与工作本身有关的内容) - 仅{{1}这些将作为JSON发布,并带有传递标签。
所以下面的回调没有正确注册(也没有错误):
dict
但是如果我删除def publish(self, item, delivery_tag):
self.log('item_scraped={0} {1}'.format(item, delivery_tag))
publish_message = json.dumps(item)
self._channel.basic_publish(exchange=self.publish_exchange,
routing_key=self.publish_key,
body=publish_message)
self._channel.basic_ack(delivery_tag=delivery_tag)
中的if
分支并直接连接回调(并修改_connect_to_signal
以吸收所有不必要的参数),它就可以工作。
任何人都有任何想法?
答案 0 :(得分:0)
所以,我通过在更一般的背景下重新陈述它来弄清楚为什么这不起作用:
import functools
from scrapy.signalmanager import SignalManager
SIGNAL = object()
class Sender(object):
def __init__(self):
self.signals = SignalManager(self)
def wrap_receive(self, receive):
@functools.wraps(receive)
def wrapped_receive(message, data):
message = message.replace('World', 'Victor')
value = data['key']
receive(message, value)
return wrapped_receive
def bind(self, receive):
_receive = self.wrap_receive(receive)
self.signals.connect(_receive, signal=SIGNAL,
sender=self, weak=False)
def send(self):
message = 'Hello, World!'
data = {'key': 'value'}
self.signals.send_catch_log(SIGNAL, message=message, data=data)
class Receiver(object):
def __init__(self, sender):
self.sender = sender
self.sender.bind(self.receive)
def receive(self, message, value):
"""Receive data from a Sender."""
print 'Receiver received: {0} {1}.'.format(message, value)
if __name__ == '__main__':
sender = Sender()
receiver = Receiver(sender)
sender.send()
当且仅当weak=False
时才有效。
基本问题是当连接信号时,需要指定weak=False
。希望比我更聪明的人可以解释为什么需要它。