python - 在 scrapy 中使用 ItemLoader 将 KeyError 处理设置为默认值
问题描述
通过scrapy教程并开始使用项目加载器来收集数据。我正在使用的数据涉及从我通过 JSON 加载的预定义字典和蜘蛛之后的产品页面中读取数据。
我遇到的问题是字典有时没有可用的键(如'salePrice'),这会导致抓取中的 KeyError 并完全停止执行。我正在尝试查看是否有一种干净的方法来处理该字段的items.py
KeyErrors,其中为每个字段指定了 input_processors 和 output_processors。
将不胜感激任何建议或例子!
import json
import re
import time
import scrapy
from scrapy.loader import ItemLoader
from tutorial.items import Product
class SephoraSpider(scrapy.Spider):
name = 'sephora-shelf'
start_urls = [
'https://www.sephora.com/shop/moisturizing-cream-oils-mists/?currentPage=1'
]
next_page_number = 1
base_url = 'https://www.sephora.com'
def parse(self, response):
json_xpath = '//script[@type="text/json" and @id="linkSPA"]/text()'
product_container = json.loads(response.xpath(json_xpath).extract()[0])
product_container = product_container['NthCategory']['props']['products']
start_time = round(time.time())
print("starting loop")
for _product in product_container:
product = Product()
loader = ItemLoader(item=Product(), response=response)
loader.add_value('list_price', _product['currentSku']['listPrice'])
loader.add_value('sale_price', _product['currentSku']['salePrice'])
loader.add_value('sku_id', _product['currentSku']['skuId'])
loader.add_value('product_key', _product['productId'])
loader.add_value('product_name', _product['displayName'])
loader.add_value('brand_name', _product['brandName'])
loader.add_value('product_id', _product['productId'])
_product_url = self.base_url + _product['targetUrl']
loader.add_value('product_url', _product_url)
loader.add_value('status', None)
print("finished loading product")
# TODO: add a check to see if it was on the previous run's data
# to determine if it is product status: added / deleted.
# Only collect product data if the product is newly added.
yield response.follow(_product_url, callback=self.parse_product,
meta={'item':loader.load_item()})
next_page_xpath = '//button[@type="button" and @aria-label="Next"]'
next_page_button = response.xpath(next_page_xpath)
print(f'next_page_button: {next_page_button}')
if next_page_button:
print("Inside next_page_button")
SephoraSpider.next_page_number += 1
next_page = re.sub('\?currentPage=[0-9]*',
'?currentPage=' +
str(SephoraSpider.next_page_number),
response.request.url)
print(f"Next Page: {next_page}")
yield response.follow(next_page, callback=self.parse)
def parse_product(self, response):
loader = ItemLoader(item=response.meta['item'],
response=response)
loader.add_xpath('item_id', '//div[@data-at="sku_size"]')
time.sleep(3)
yield loader.load_item()
解决方案
一种简单的解决方法是使用字典的 .get() 方法,并在缺少键时将其默认为 None 。仍然不相信这是否是处理scrapy时处理此类错误的正确方法。
前:loader.add_value('sale_price', _product['currentSku']['salePrice'])
后: loader.add_value('sale_price', _product.get('currentSku').get('salePrice', None))
推荐阅读
- android - 通过 ViewModel 从 SQL 连接器更新 Jetpack Compose UI
- python - Pandas 数据框为多列的每个值创建新行
- node.js - 将firebase电子邮件基本网址更改为自定义域
- c++ - 如何使用字段名称初始化这些结构?
- python - 从 Python 和 BeautifulSoup 的搜索结果中抓取 url
- java - 在同一台机器上的微服务之间进行通信,而不暴露公共 API
- ffmpeg - 如何在 Windows 10 上为 FFMPEG 配置 --enable-libfreetype?
- python - 使用 Python 的图同态
- jquery - 使用 jQuery 将鼠标悬停在 div 上时如何在所有内容上创建 div
- javascript - 在浏览器上播放警报声音不会立即发生