如何在start\u requests方法完成之前让Scrapy执行回调?
我有一个很大的相对URL文件,我想用Scrapy来清理,我已经编写了一些代码来逐行阅读这个文件,并为我的爬行器生成解析请求。下面是一些示例代码 蜘蛛网:如何在start\u requests方法完成之前让Scrapy执行回调?,scrapy,twisted,scrapy-spider,Scrapy,Twisted,Scrapy Spider,我有一个很大的相对URL文件,我想用Scrapy来清理,我已经编写了一些代码来逐行阅读这个文件,并为我的爬行器生成解析请求。下面是一些示例代码 蜘蛛网: def start_requests(self): with open(self._file) as infile: for line in infile: inlist = line.replace("\n","").split(",") item = MyItem(da
def start_requests(self):
with open(self._file) as infile:
for line in infile:
inlist = line.replace("\n","").split(",")
item = MyItem(data = inlist[0])
request = scrapy.Request(
url = "http://foo.org/{0}".format(item["data"]),
callback = self.parse_some_page
)
request.meta["item"]
yield request
def parse_some_page(self,response):
...
request = scrapy.Request(
url = "http://foo.org/bar",
callback = self.parse_some_page2
)
yield request
这很好,但是对于一个大的输入文件,我发现在
start\u请求
生成所有初始请求之前,parse\u一些页面2
不会被调用。有什么方法可以让Scrapy更早地开始调用回调吗?最终,我不想等到一百万个请求之后才开始看到项目在管道中流动。我想出了两个解决方案。1) 如果大型站点太多,则在单独的进程中运行spider。2) 通过Twisted使用延迟和回调(请不要逃跑,这不会太可怕)。我将讨论如何使用第二种方法,因为第一种方法可以简单地用谷歌搜索
执行屈服请求的每个函数将“阻塞”,直到结果可用。因此,您的parse_some_page()
函数将生成一个不完整的响应对象,并且在返回响应之前不会转到下一个URL。我确实找到了一些网站(主要是外国政府网站),它们需要一段时间才能获取,希望它能模拟您正在经历的类似情况。下面是一个简单的例子:
#spider/stackoverflow_spider.py
从twisted.internet导入延迟
进口羊瘙痒
类StackOverflow(scrapy.Spider):
名称='stackoverflow'
def start_请求(自我):
URL=[
'http://www.gob.cl/en/',
'http://www.thaigov.go.th/en.html',
'https://www.yahoo.com',
'https://www.stackoverflow.com',
'https://swapi.co/',
]
对于索引,枚举中的url(url):
#在返回响应后创建回调链
deferred=deferred.deferred()
deferred.addCallback(self.parse\u some\u页面)
deferred.addCallback(self.write_到_磁盘,url=url,filenumber=index+1)
#根据需要添加回调和错误回调
请按我的要求(
url=url,
callback=deferred.callback)#此函数将在返回响应后启动回调链
def解析某些页面(自我,响应):
打印(“[1]正在分析%s%”(response.url))
return response.body#这将传递给下一个回调
def写入磁盘(自身、内容、url、文件号):
打印(“[2]正在将%s内容写入磁盘“%”(url))
文件名=“%d.html”%filenumber
将open(filename,'wb')作为f:
f、 写作(内容)
#返回要传递给下一个回调函数的内容
#或者引发错误并启动Errbacks链
我稍微做了一些改变,使它更易于阅读和运行。在start\u requests()
中要注意的第一件事是在url
循环中创建对象并链接回调函数(通过addCallback()
)。现在查看scrapy.Request
的回调
参数:
yield scrapy.Request(
url=url,
callback=deferred.callback)
此代码段将做的是在请求中scrapy.Response
可用后立即启动回调链。在Twisted中,Deferreds
仅在Deferred之后才开始运行回调链。回调(结果)
使用值执行
提供响应后,parse_some_page()
函数将以response
作为参数运行。您将要做的是提取您在此处需要的内容,并将其传递给下一个回调(即write\u to\u disk()
my example)。如有必要,您可以向循环中的延迟
添加更多回调
因此,这个答案与您最初所做的不同之处在于,您使用yield
先等待所有响应,然后执行回调。其中,as-my方法使用Deferred.callback()
作为每个请求的回调,以便立即处理每个响应
希望这有帮助(和/或有效)
工具书类
- :简要总结yeild/return如何影响解析
- :我以前写过一篇关于Klien/Twisted异步回调的博文。可能对新手有帮助
附言
我不知道这是否真的适用于您,因为我找不到一个太大而无法解析的站点。另外,我在Scrapy:D是一个全新的人,但我有多年的经验。我可能错了,但我认为发生这种情况是因为你在解析某些页面()
中产生了结果。当您删除了yield时会发生什么情况?@san臭名昭著。不,如果我选择省略yield
,我不知道该如何处理新请求。谢谢您这么好的回复!我要试试看,读一些东西,然后再给你回复。