Scrapy 请求不回调
Scrapy request does not callback
我正在尝试创建一个从 csv 中获取数据的蜘蛛(每行两个 link 和一个名称),并从每个 link 中抓取一个简单的元素(价格) s,为每一行返回一个项目,项目的名称是 csv 中的名称,以及两个抓取的价格(每个 link)。
除了不是返回价格,而是从每个请求的回调函数返回的价格,一切都按预期工作,我得到一个这样的请求对象:
<获取https://link.com>..
回调函数根本没有被调用,这是为什么?
这是蜘蛛:
f = open('data.csv')
f_reader = csv.reader(f)
f_data = list(f_reader)
parsed_data = []
for product in f_data:
product = product[0].split(';')
parsed_data.append(product)
f.close()
class ProductSpider(scrapy.Spider):
name = 'products'
allowed_domains = ['domain1', 'domain2']
start_urls = ["domain1_but_its_fairly_useless"]
def parse(self, response):
global parsed_data
for product in parsed_data:
item = Product()
item['name'] = product[0]
item['first_price'] = scrapy.Request(product[1], callback=self.parse_first)
item['second_price'] = scrapy.Request(product[2], callback=self.parse_second)
yield item
def parse_first(self, response):
digits = response.css('.price_info .price span').extract()
decimals = response.css('.price_info .price .price_demicals').extract()
yield float(str(digits)+'.'+str(decimals))
def parse_second(self, response):
digits = response.css('.lr-prod-pricebox-price .lr-prod-pricebox-price-primary span[itemprop="price"]').extract()
yield digits
在此先感谢您的帮助!
TL;DR:当您应该生成项目或请求时,您正在生成其中包含请求对象的项目。
长版:
蜘蛛中的解析方法应该 return a scrapy.Item
- 在这种情况下,该爬行的链将停止并且 scrapy 将推出一个项目或 scrapy.Requests
在这种情况下 scrapy 将安排一个请求继续链。
Scrapy 是异步的,所以从多个请求创建一个项目意味着你需要将所有这些请求链接起来,同时将你的项目带到每个项目并一点一点地填充它。
Request 对象有 meta
属性,你可以在其中存储任何你想要的东西(非常多),它会被传送到你的回调函数。使用它来链接对需要多个请求以形成单个项目的项目的请求是很常见的。
你的蜘蛛应该看起来像这样:
class ProductSpider(scrapy.Spider):
# <...>
def parse(self, response):
for product in parsed_data:
item = Product()
item['name'] = product[0]
# carry next url you want to crawl in meta
# and carry your item in meta
yield Request(product[1], self.parse_first,
meta={"product3": product[2], "item":item})
def parse_first(self, response):
# retrieve your item that you made in parse() func
item = response.meta['item']
# fill it up
digits = response.css('.price_info .price span').extract()
decimals = response.css('.price_info .price .price_demicals').extract()
item['first_price'] = float(str(digits)+'.'+str(decimals))
# retrieve next url from meta
# carry over your item to the next url
yield Request(response.meta['product3'], self.parse_second,
meta={"item":item})
def parse_second(self, response):
# again, retrieve your item
item = response.meta['item']
# fill it up
digits = response.css('.lr-prod-pricebox-price .lr-prod-pricebox-price-primary
span[itemprop="price"]').extract()
item['secodn_price'] = digits
# and finally return the item after 3 requests!
yield item
我正在尝试创建一个从 csv 中获取数据的蜘蛛(每行两个 link 和一个名称),并从每个 link 中抓取一个简单的元素(价格) s,为每一行返回一个项目,项目的名称是 csv 中的名称,以及两个抓取的价格(每个 link)。
除了不是返回价格,而是从每个请求的回调函数返回的价格,一切都按预期工作,我得到一个这样的请求对象:
<获取https://link.com>..
回调函数根本没有被调用,这是为什么?
这是蜘蛛:
f = open('data.csv')
f_reader = csv.reader(f)
f_data = list(f_reader)
parsed_data = []
for product in f_data:
product = product[0].split(';')
parsed_data.append(product)
f.close()
class ProductSpider(scrapy.Spider):
name = 'products'
allowed_domains = ['domain1', 'domain2']
start_urls = ["domain1_but_its_fairly_useless"]
def parse(self, response):
global parsed_data
for product in parsed_data:
item = Product()
item['name'] = product[0]
item['first_price'] = scrapy.Request(product[1], callback=self.parse_first)
item['second_price'] = scrapy.Request(product[2], callback=self.parse_second)
yield item
def parse_first(self, response):
digits = response.css('.price_info .price span').extract()
decimals = response.css('.price_info .price .price_demicals').extract()
yield float(str(digits)+'.'+str(decimals))
def parse_second(self, response):
digits = response.css('.lr-prod-pricebox-price .lr-prod-pricebox-price-primary span[itemprop="price"]').extract()
yield digits
在此先感谢您的帮助!
TL;DR:当您应该生成项目或请求时,您正在生成其中包含请求对象的项目。
长版:
蜘蛛中的解析方法应该 return a scrapy.Item
- 在这种情况下,该爬行的链将停止并且 scrapy 将推出一个项目或 scrapy.Requests
在这种情况下 scrapy 将安排一个请求继续链。
Scrapy 是异步的,所以从多个请求创建一个项目意味着你需要将所有这些请求链接起来,同时将你的项目带到每个项目并一点一点地填充它。
Request 对象有 meta
属性,你可以在其中存储任何你想要的东西(非常多),它会被传送到你的回调函数。使用它来链接对需要多个请求以形成单个项目的项目的请求是很常见的。
你的蜘蛛应该看起来像这样:
class ProductSpider(scrapy.Spider):
# <...>
def parse(self, response):
for product in parsed_data:
item = Product()
item['name'] = product[0]
# carry next url you want to crawl in meta
# and carry your item in meta
yield Request(product[1], self.parse_first,
meta={"product3": product[2], "item":item})
def parse_first(self, response):
# retrieve your item that you made in parse() func
item = response.meta['item']
# fill it up
digits = response.css('.price_info .price span').extract()
decimals = response.css('.price_info .price .price_demicals').extract()
item['first_price'] = float(str(digits)+'.'+str(decimals))
# retrieve next url from meta
# carry over your item to the next url
yield Request(response.meta['product3'], self.parse_second,
meta={"item":item})
def parse_second(self, response):
# again, retrieve your item
item = response.meta['item']
# fill it up
digits = response.css('.lr-prod-pricebox-price .lr-prod-pricebox-price-primary
span[itemprop="price"]').extract()
item['secodn_price'] = digits
# and finally return the item after 3 requests!
yield item