`如何在scrapy中使用回调链
`How to use a chain of callbacks in scrapy
我正在尝试使用 scrapy 和 selenium webdriver 构建一个爬虫。我正在尝试在 parse()
中获取一组 url 并将其传递给回调函数 parse_url()
,该函数再次获取一组不同的 url 并将其传递给 parse_data()
parse_url
的第一个回调有效,但 parse_data
的第二个回调给出 AssertionError
即如果我 运行 没有 parse_data
它会打印一个 url 列表。但是如果我包含它,我会得到一个断言错误
我有这样的东西
class mySpider(scrapy.Spider):
name = "mySpider"
allowed_domains = ["example.com"]
start_urls = [
"http://www.example.com/url",
]
def parse(self, response):
driver = webdriver.firefox()
driver.get(response.url)
urls = get_urls(driver.page_source) # get_url returns a list
yield scrapy.Request(urls, callback=self.parse_url(urls, driver))
def parse_url(self, url, driver):
url_list = []
for i in urls:
driver.get(i)
url_list.append( get_urls(driver.pagesource)) # gets some more urls
yeild scrapy.Request(urls, callback=self.parse_data(url_list, driver))
def parse_data(self, url_list, driver):
data = get_data(driver.pagesource)
这是回溯,
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/scrapy/utils/defer.py", line 45, in mustbe_deferred
result = f(*args, **kw)
File "/usr/local/lib/python2.7/dist-packages/scrapy/core/spidermw.py", line 48, in process_spider_input
return scrape_func(response, request, spider)
File "/usr/local/lib/python2.7/dist-packages/scrapy/core/scraper.py", line 145, in call_spider
dfd.addCallbacks(request.callback or spider.parse, request.errback)
File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 299, in addCallbacks
assert callable(callback)
AssertionError
有两个问题:
您没有将函数传递给请求。您正在将函数的 return 值传递给请求。
Request的回调函数必须有签名(self, response)。
动态内容的解决方案在这里:
它将消除将驱动程序传递到函数中的需要。
所以当你提出你的请求时,它应该是这样的......
scrapy.Request(urls, callback=self.parse_url)
如果您确实想要包含具有该功能的驱动程序,请阅读有关闭包的内容。
编辑:这是一个关闭解决方案,但我认为您应该使用我分享的 link,因为 GHajba 指出的原因。
def parse_data(self, url_list, driver):
def encapsulated(spider, response)
data = get_data(driver.pagesource)
.....
.....
yield item
return encapsulated
那么你的请求看起来像
yield scrapy.request(url, callback=self.parse_data(url_list, driver)
我正在尝试使用 scrapy 和 selenium webdriver 构建一个爬虫。我正在尝试在 parse()
中获取一组 url 并将其传递给回调函数 parse_url()
,该函数再次获取一组不同的 url 并将其传递给 parse_data()
parse_url
的第一个回调有效,但 parse_data
的第二个回调给出 AssertionError
即如果我 运行 没有 parse_data
它会打印一个 url 列表。但是如果我包含它,我会得到一个断言错误
我有这样的东西
class mySpider(scrapy.Spider):
name = "mySpider"
allowed_domains = ["example.com"]
start_urls = [
"http://www.example.com/url",
]
def parse(self, response):
driver = webdriver.firefox()
driver.get(response.url)
urls = get_urls(driver.page_source) # get_url returns a list
yield scrapy.Request(urls, callback=self.parse_url(urls, driver))
def parse_url(self, url, driver):
url_list = []
for i in urls:
driver.get(i)
url_list.append( get_urls(driver.pagesource)) # gets some more urls
yeild scrapy.Request(urls, callback=self.parse_data(url_list, driver))
def parse_data(self, url_list, driver):
data = get_data(driver.pagesource)
这是回溯,
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/scrapy/utils/defer.py", line 45, in mustbe_deferred
result = f(*args, **kw)
File "/usr/local/lib/python2.7/dist-packages/scrapy/core/spidermw.py", line 48, in process_spider_input
return scrape_func(response, request, spider)
File "/usr/local/lib/python2.7/dist-packages/scrapy/core/scraper.py", line 145, in call_spider
dfd.addCallbacks(request.callback or spider.parse, request.errback)
File "/usr/local/lib/python2.7/dist-packages/twisted/internet/defer.py", line 299, in addCallbacks
assert callable(callback)
AssertionError
有两个问题:
您没有将函数传递给请求。您正在将函数的 return 值传递给请求。
Request的回调函数必须有签名(self, response)。
动态内容的解决方案在这里:
它将消除将驱动程序传递到函数中的需要。
所以当你提出你的请求时,它应该是这样的......
scrapy.Request(urls, callback=self.parse_url)
如果您确实想要包含具有该功能的驱动程序,请阅读有关闭包的内容。
编辑:这是一个关闭解决方案,但我认为您应该使用我分享的 link,因为 GHajba 指出的原因。
def parse_data(self, url_list, driver):
def encapsulated(spider, response)
data = get_data(driver.pagesource)
.....
.....
yield item
return encapsulated
那么你的请求看起来像
yield scrapy.request(url, callback=self.parse_data(url_list, driver)