很抱歉,我无法用更简单的示例重现错误,而且我的代码太复杂而无法发布.如果我在IPython shell而不是常规Python中运行程序,那么事情就会很顺利.
我查看了之前关于这个问题的一些注意事项.它们都是由在类函数中定义的pool to call函数引起的.但对我来说情况并非如此.
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 313, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Run Code Online (Sandbox Code Playgroud)
我将不胜感激任何帮助.
更新:我挑选的功能是在模块的顶层定义的.虽然它调用包含嵌套函数的函数.即f()要求g()调用h()具有嵌套函数i(),和我打电话pool.apply_async(f).f(),g(),h()都在顶层定义.我用这个模式尝试了更简单的例子,但它确实有效.
我得到的twisted.internet.error.ReactorNotRestartable错误,当我执行下面的代码:
from time import sleep
from scrapy import signals
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy.xlib.pydispatch import dispatcher
result = None
def set_result(item):
result = item
while True:
process = CrawlerProcess(get_project_settings())
dispatcher.connect(set_result, signals.item_scraped)
process.crawl('my_spider')
process.start()
if result:
break
sleep(3)
Run Code Online (Sandbox Code Playgroud)
它第一次起作用,然后我得到错误.我process每次创建变量,那么问题是什么?
我的草率代码如下所示:
import scrapy
from scrapy.crawler import CrawlerProcess
class MovieSpider(scrapy.Spider):
name = "movies"
start_urls = [
'https://movie.douban.com/subject/25934014/',
'https://movie.douban.com/subject/25852314/',
]
def parse(self, response):
title = response.css('div#wrapper div#content h1 span::text').extract_first()
year = response.css('div#wrapper div#content h1 span.year::text').extract_first()
yield {
'url': response.url,
'title': title,
'year': year,
}
Run Code Online (Sandbox Code Playgroud)
我这样运行
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
'FEED_FORMAT': 'json',
'FEED_URI': 'movie.json',
'FEED_EXPORT_ENCODING':'utf-8'
})
process.crawl(MovieSpider)
process.start() #
Run Code Online (Sandbox Code Playgroud)
这是docs中推荐的方式。
问题在于,运行上述脚本后,无法再次运行它。Jupyter Notebook返回错误ReactorNotRestartable
如果我在jupyter中重新启动内核,则可以第一次运行。
我认为问题是在脚本的Scrapy抓取中指出的,始终在抓取后阻止脚本执行
我可能可以通过使用他们的代码来解决此问题。但是,对于这么小的事情,它们的代码非常复杂,并且CrawlerProcess与文档中推荐的方式相去甚远。
我想知道是否有更好的方法来解决这个问题? …
我跑Scrapy (1.4.0版本)使用的脚本CrawlerProcess。网址来自用户输入。第一次运行良好,但第二次twisted.internet.error.ReactorNotRestartable出现错误。所以,程序卡在那里。
爬虫进程部分:
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(GeneralSpider)
print('~~~~~~~~~~~~ Processing is going to be started ~~~~~~~~~~')
process.start()
print('~~~~~~~~~~~~ Processing ended ~~~~~~~~~~')
process.stop()
Run Code Online (Sandbox Code Playgroud)
这是第一次运行输出:
~~~~~~~~~~~~ Processing is going to be started ~~~~~~~~~~
2017-07-17 05:58:46 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.some-url.com/content.php> (referer: None)
2017-07-17 05:58:46 [scrapy.core.scraper] ERROR: Spider must return Request, BaseItem, dict or None, got 'HtmlResponse' in <GET http://www.some-url.com/content.php>
2017-07-17 05:58:46 [scrapy.core.engine] INFO: Closing spider (finished)
2017-07-17 05:58:46 …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Google Cloud Functions 发送多个抓取请求。但是,我似乎收到了错误ReactorNotRestartable。从 StackOverflow 上的其他帖子(例如这篇文章)中,我了解到这是因为无法重新启动反应器,特别是在执行循环时。
解决这个问题的方法是把start()for循环放在外面。但是,对于云功能,这是不可能的,因为每个请求在技术上都应该是独立的。
是否以CrawlerProcess某种方式使用 Cloud Functions 进行缓存?如果是这样,我们如何消除这种行为。
例如,我尝试将导入和初始化过程放在函数内部而不是外部,以防止缓存导入,但这不起作用:
# main.py
def run_single_crawl(data, context):
from scrapy.crawler import CrawlerProcess
process = CrawlerProcess()
process.crawl(MySpider)
process.start()
Run Code Online (Sandbox Code Playgroud)