Python爬取Cartier官网商品价格失败,寻求解决方法
问题分析与解决方案
你的代码主要有两个关键错误导致无法获取价格:
- JSON结构解析错误:网页中的
application/ld+json内容外层是数组([{...}]),json.loads解析后得到的是列表而非字典,直接用data['offers']会触发类型错误。 - offers字段结构错误:
offers字段的值同样是一个数组([{"@type": "Offer", ...}]),需要取数组内的第一个元素才能访问price。
另外,函数内的变量data与全局变量data重名,虽不会直接报错但易造成混淆,建议修改。
修正后的代码
import json from bs4 import BeautifulSoup import requests from multiprocessing import Pool import pandas as pd # 全局存储数据的字典 result_data = {'url':[],'offers_price':[]} def get_price(url): try: response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'}) response.raise_for_status() # 捕获HTTP请求错误 soup = BeautifulSoup(response.content, "html.parser") # 找到目标script标签,取最后一个匹配的结果 script_tag = soup.find_all('script', {'type': 'application/ld+json'})[-1] # 清理文本多余空格换行,避免解析错误 json_text = script_tag.get_text().strip() # 解析JSON,外层是列表,取第一个Product对象 product_data = json.loads(json_text)[0] # offers是列表,取第一个Offer对象的价格 price = int(product_data['offers'][0]['price']) return url, price except Exception as e: print(f"处理URL {url}时出错: {str(e)}") return url, None if __name__ == '__main__': urls = ['https://www.cartier.com/en-gb/love-bracelet-small-model_cod25372685655708131.html#dept=EU_Love'] with Pool(processes=4) as pool: for url, price in pool.imap_unordered(get_price, urls): if price is not None: result_data['offers_price'].append(price) result_data['url'].append(url) print(result_data)
关键修改点说明
- JSON解析修正:添加
[0]取出列表中的第一个Product对象:product_data = json.loads(json_text)[0] - offers字段访问修正:通过
product_data['offers'][0]['price']取出第一个Offer的价格 - 变量名优化:将全局存储数据的字典改为
result_data,避免与函数内的解析变量冲突 - 异常处理:添加
try-except块捕获请求、解析过程中的错误,避免单个URL异常导致整个任务终止 - 请求头优化:使用更完整的User-Agent,降低被反爬拦截的概率
内容的提问来源于stack exchange,提问作者Seedizens
相关产品推荐
相关产品推荐

