python - Scrapy - 不能做多个回调
问题描述
我在浏览多个页面时遇到问题。这是我的名为引号的scrapy代码课程。
class quotes(scrapy.Spider):
name = 'quotes'
start_urls = ['http://books.toscrape.com/?']
def parse(self, response):
all_links = response.css('.nav-list ul li')
for links in all_links:
link = links.css('a::attr(href)').get()
yield response.follow(link, callback = self.books_detail)
def books_detail(self, response):
yas = {
'title':[],
'price':[],
'availability':[],
'category':[]
}
yas['category'].append(response.css('h1::text').extract())
all_divs = response.css('.col-lg-3')
for div in all_divs:
link = div.css('.product_pod a::attr(href)').get()
title = response.follow(link, callback = self.get_title)
yas['price'].append(div.css('.price_color::text').extract())
yas['availability'].append(div.css('.availability::text')[1].extract())
yield yas
def get_title(self,response):
print('testing')
title = response.css('h1::text').extract()
yield {"title":title}
所以我使用 response.follow 转到函数books_details并在该函数中,我再次调用 response.follow 来调用get_title。我从 get_title 获取“标题”,从主页获取其他详细信息。我可以从books_details函数中很好地抓取信息,也可以从代码行中很好地获取标题页的链接。
link = div.css('.product_pod a::attr(href)').get()
但是使用 response.follow 我不能去 get_title 功能。 任何帮助,将不胜感激。谢谢。
解决方案
您应该产生请求,而不是直接运行它,并用于meta=
将数据发送到下一个解析器
yield response.follow(link, callback=self.get_title, meta={'item': yas})
在下一个解析器中你可以得到它
yas = response.meta['item']
然后您可以添加新值并生成所有数据
yas["title"] = response.css('h1::text').extract()
yield yas
请参阅Scrapy yield items from multiple requests中的其他示例
Doc: Request 和 Response , Request.meta 特殊键
您可以将其放在一个文件中并作为普通脚本 ( python script.py
) 运行而无需创建项目的最少工作代码。
还有其他变化。
您不应该将所有书籍都放在一个列表中,而应分别生成每本书。Scrapy 将保留所有结果,当您使用选项保存在 csv 中时,它将保存所有结果。
对于每本书,您都应该创建新词典。如果您多次使用同一个字典,那么它将覆盖数据,并且您可能会使用相同的数据获得许多结果。
import scrapy
class QuotesSpider(scrapy.Spider):
name = 'quotes'
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
all_links = response.css('.nav-list ul li')
for links in all_links:
link = links.css('a::attr(href)').get()
yield response.follow(link, callback=self.books_detail)
def books_detail(self, response):
all_divs = response.css('.col-lg-3')
for div in all_divs:
# every book in separated dictionary and it has to be new dictionary - because it could overwrite old data
book = {
'category': response.css('h1::text').extract(),
'price': div.css('.price_color::text').extract()[0].strip(),
'availability': div.css('.availability::text')[1].extract().strip(),
}
link = div.css('.product_pod a::attr(href)').get()
yield response.follow(link, callback=self.get_title, meta={'item': book})
def get_title(self, response):
book = response.meta['item']
print('testing:', response.url)
book["title"] = response.css('h1::text').extract()[0].strip()
yield book
# --- run without project and save in `output.csv` ---
from scrapy.crawler import CrawlerProcess
c = CrawlerProcess({
'USER_AGENT': 'Mozilla/5.0',
# save in file CSV, JSON or XML
'FEED_FORMAT': 'csv', # csv, json, xml
'FEED_URI': 'output.csv', #
})
c.crawl(QuotesSpider)
c.start()
推荐阅读
- truffle - 松露配置中指定的网络 ID 与网络返回的网络 ID 不匹配
- python - 在 python openCV 上的网络摄像头视频上选择静态 ROI
- svelte - 带有 typescript 和 scss 支持的 svelte/sapper 的 Webpack 配置
- python - 小部件不透明度上的 QPropertyAnimation 在调整大小时重新启动,导致窗口闪烁/闪烁
- c++ - “无法将 (null)::newConnection() 连接到 myserver::onNewConnection()” - 未调用 newConnection 信号
- terminal - 在启动时运行终端并以 sudo 执行命令
- python - Keras 在单个 epoch 中打印出每批的结果,这是为什么呢?
- python - 非相邻对之间的 pct_change
- sql - 复合键中的一个字段可以依赖于另一个字段吗?
- java - Fetching data using hibernate with Netbeans