如何从HTML的JSON子节点提取数据?解决JSONDecodeError问题
解决Bergzeit网站商品数据提取的JSON解析错误
问题根源
爬取https://www.bergzeit.de/marken/salewa/商品数据时,原代码直接用json.loads解析包含elementsList的脚本报错,核心原因有两个:
- 目标脚本是JavaScript代码片段,不是纯JSON——它是赋值给
window.__initialAppState的对象,开头带window.__initialAppState =,结尾有;,不符合JSON格式要求。 - 脚本里存在
JSON.parse("\"Salewa\"")这类JS函数调用,JSON规范不允许这种语法结构。
修复步骤与代码
1. 提取脚本中的纯对象内容
先过滤出包含window.__initialAppState的脚本,再用正则截取等号之后、分号之前的对象部分。
2. 兼容JS语法到JSON
把脚本里的JSON.parse调用替换成JSON能识别的字面量值。
3. 解析并提取目标数据
完整代码示例:
import json import re # 假设response是Scrapy的响应对象 scripts = response.xpath('//script/text()').getall() # 定位目标脚本 target_script = next((s for s in scripts if 'window.__initialAppState' in s), None) if target_script: # 截取JS对象部分 match = re.search(r'window.__initialAppState = ({.*?});', target_script, re.DOTALL) if match: data_str = match.group(1) # 替换JSON.parse调用为JSON兼容值 data_str = re.sub(r'JSON.parse\("\\"(.*?)\\"\)"', r'"\1"', data_str) data_str = re.sub(r'JSON.parse\("null"\)', 'null', data_str) # 解析JSON try: app_data = json.loads(data_str) # 获取商品列表 products_list = app_data['modules']['productsListPage']['elementsList'] # 提取所需字段 for item in products_list: product = item['data'] # 基础信息 name = product['name'] current_price = product['price']['current'] full_url = f"https://www.bergzeit.de{product['url']}" # 提取颜色和尺寸 available_colors = [] available_sizes = [] for var in product['variations']: if var['colorVariation']: # 筛选可选颜色 available_colors = [opt['label'] for opt in var['options'] if opt['isAvailable'] or opt['isAnyAvailable']] else: # 筛选可选尺寸 available_sizes = [opt['label'] for opt in var['options'] if opt['isAvailable'] or opt['isAnyAvailable']] # 输出或存储数据 print(f"商品名称: {name}") print(f"当前价格: {current_price}") print(f"商品链接: {full_url}") print(f"可选颜色: {', '.join(available_colors) if available_colors else '暂无'}") print(f"可选尺寸: {', '.join(available_sizes) if available_sizes else '暂无'}") print("------------------------") except json.JSONDecodeError as e: print(f"解析失败: {str(e)}") else: print("未找到包含商品数据的脚本")
代码说明
- 用
next()快速定位目标脚本,避免无意义遍历。 - 正则替换处理JS的
JSON.parse语法,确保内容符合JSON规范。 - 从
modules.productsListPage.elementsList拿到商品数据,再从variations字段分离颜色和尺寸,筛选出可选的选项。
内容的提问来源于stack exchange,提问作者Vaidas
相关产品推荐
相关产品推荐

