python - Scrapy:按顺序抓取网页并在自定义函数中生成抓取的数据
问题描述
我想使用 Scrapy 抓取市场网站以查找已售商品。我想一次做一个项目,因为,例如,如果我调用第 555566 号项目,但没有这样的项目,网页只会显示“不正确的项目”,我只能在响应通过后关闭蜘蛛. 到那时,Scrapy 将调用更多页面,而我不希望这样。
Scrapy首先在方法中爬取起始商品页面start_requests
,然后在方法中调用api获取该特定商品的销售数据parse
,然后在方法中提取数据parse_item
。我想在一个单独的函数中产生这些数据,因为我需要在start_requests
方法末尾使用下一个项目编号再次调用该parse_item
方法。
这就是我正在努力解决的部分。
再打电话
start_requests
就不行了。如果我注释掉函数中的
yield
命令yield_data
,该项目就会很好地打印在控制台中。但是在yield
未注释命令的情况下,程序似乎甚至没有进入该yield_data
功能。这是为什么?
我很感激这方面的任何帮助。这是代码:
import scrapy
import json
from scrapy.exceptions import CloseSpider
class_itemsSpider(scrapy.Spider):
name = 'items'
id = 555555
def start_requests(self):
url = 'https://market.com/item/' + str(self.id)
index = self.id
self.id += 1
yield scrapy.Request(url, meta={'index':index})
def parse(self, response):
index = response.meta['index']
if b'Incorrect' in response.body:
raise CloseSpider('Incorrect item')
url = 'https://market.com/api/item?ajax=1&itemid=' + str(index)
request = scrapy.Request(url, callback=self.parse_item,
headers={
'accept': 'application/json, text/plain, */*',
'user-agent': 'Mozilla/5.0'
})
yield request
def parse_item(self, response):
raw_data = response.body
data = json.loads(raw_data)
item = {
'Name':data['name'],
'Price':data['price'],
}
self.yield_data(item)
# call start_requests again
self.start_requests()
def yield_data(self,_item):
self.logger.info('Printing_item')
print(item)
self.logger.info('Yielding_item')
yield item
解决方案
好的,我想通了。也许它会帮助某人。我想yield
作为完成代码执行的东西,但你可以产生数据,然后产生一个带有回调parse
方法的请求。
import scrapy
import json
from scrapy.exceptions import CloseSpider
class_itemsSpider(scrapy.Spider):
name = 'items'
id = 555555
start_urls = ['https://market.com/item/' + str(id)]
def parse(self, response):
if b'Invalid' in response.body:
raise CloseSpider('Invalid item')
index = self.id
self.id += 1
url = 'https://market.com/api/item?ajax=1&itemid=' + str(index)
request = scrapy.Request(url, callback=self.parse_item,
headers={
'accept': 'application/json, text/plain, */*',
'user-agent': 'Mozilla/5.0'},
meta={'index':index})
yield request
def parse_item(self, response):
index = response.meta['index']
raw_data = response.body
data = json.loads(raw_data)
yield {
'Name':data['name'],
'Price':data['price'],
}
url = 'https://market.com/item/' + str(self.id)
yield scrapy.Request(url, callback=self.parse)
推荐阅读
- node.js - 如何将抓取的数据发送到索引 html 文件以加载
- python - 挂载作业输出数据作为 Floydhub 中另一个作业的输入数据
- python-3.x - 在散景渲染后是否可以将边缘/节点信息返回给 python?
- c++ - 如何找出字符串是否只有数字,没有字母
- c# - 有没有办法在 WebAPI 中不引用 EntityFramework?
- angular - 到前一个组件的角度路由不起作用
- cpu - 操作系统中的上下文切换
- bixby - 如何让 bixby 使用 app-launch 打开谷歌地图?
- react-native - 有没有办法在 Firebird 数据库和 React-Native 应用程序之间建立连接?
- java - Java EE 7 - 如何从容器内部启动事务?