Python抓取HTML页面后,如何获取window.INITIAL_DATA的JSON数据?
问题描述
我有一个商品页面:https://www.svenssons.se/varumarken/swedese/lamino-fatolj-och-fotpall-lackad-bokfarskinn/?variantId=514023-01。检查其HTML后发现所有信息都以JSON格式存放在script标签的window.INITIAL_DATA = JSON.parse('{"pa...')代码中。我尝试用requests抓取HTML并通过正则提取JSON字符串,但代码破坏了JSON结构,导致无法用json.loads()加载:
response = requests.get('https://www.svenssons.se/varumarken/swedese/lamino-fatolj-och-fotpall-lackad-bokfarskinn/?variantId=514023-01', headers=headers) soup = BeautifulSoup(response.text, 'html.parser') regex = "JSON.parse\(.*;" match = re.search(regex, str(soup)) json_string = match.group(0).replace("JSON.parse(", "")[1:-3] json_data = json.loads(json_string)
最终出现JSON解析错误:
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 22173 (char 22172)
请问是否有方法获取该JSON数据,或者更优的是,如何在Python中直接执行HTML响应中的window.INITIAL_DATA赋值逻辑?
解决方案
方法一:精准提取并解析JSON字符串
你的正则和字符串处理逻辑过于粗糙,导致破坏了原始JSON的结构。可以按以下步骤优化:
- 先定位到包含
window.INITIAL_DATA的script标签,避免将整个soup转为字符串搜索,减少干扰。 - 使用更精准的正则匹配
JSON.parse('...')内部的JSON内容,正确处理转义字符。
示例代码:
import requests import re import json from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } url = "https://www.svenssons.se/varumarken/swedese/lamino-fatolj-och-fotpall-lackad-bokfarskinn/?variantId=514023-01" response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 定位目标script标签 target_script = None for script in soup.find_all('script'): if 'window.INITIAL_DATA = JSON.parse(' in script.text: target_script = script.text break if target_script: # 匹配JSON.parse单引号内的内容,re.DOTALL允许跨行匹配 match_result = re.search(r"JSON.parse\('(.*?)'\);", target_script, re.DOTALL) if match_result: # 还原转义的单引号,因为原JSON内部的单引号被转义为\' raw_json = match_result.group(1).replace(r"\'", "'") try: json_data = json.loads(raw_json) print("JSON解析成功") # 示例:打印商品名称 print(json_data.get('product', {}).get('name')) except json.JSONDecodeError as e: print(f"解析失败:{str(e)}") else: print("未匹配到目标JSON内容") else: print("未找到包含window.INITIAL_DATA的script标签")
方法二:直接执行JavaScript逻辑获取数据
如果不想手动处理JSON转义的问题,可以用execjs库模拟浏览器环境执行这段JS代码,直接拿到window.INITIAL_DATA的值:
- 先安装依赖:
pip install PyExecJS(依赖本地Node.js环境,需提前安装) - 执行代码:
import requests import execjs from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } url = "https://www.svenssons.se/varumarken/swedese/lamino-fatolj-och-fotpall-lackad-bokfarskinn/?variantId=514023-01" response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 定位目标script标签 target_script = None for script in soup.find_all('script'): if 'window.INITIAL_DATA = JSON.parse(' in script.text: target_script = script.text break if target_script: # 模拟浏览器的window对象,执行JS代码 ctx = execjs.compile(""" var window = {}; """ + target_script) initial_data = ctx.eval("window.INITIAL_DATA") print("JS执行成功") # 示例:打印商品名称 print(initial_data.get('product', {}).get('name')) else: print("未找到包含window.INITIAL_DATA的script标签")
内容的提问来源于stack exchange,提问作者PetrSevcik
相关产品推荐
相关产品推荐

