如何在Scrapy中从已提取的script文本获取products变量的值?
从JavaScript脚本中提取window.searchResult.products的最佳方法
下面是几种实用的解决方案,按推荐优先级排序:
方法1:正则匹配 + JSON解析(无额外依赖,推荐)
这种方法无需安装第三方库,适合大多数格式规范的JS对象场景:
import re import json # 已通过Scrapy获取的script文本 script = response.css('[id="server-side-container"] script::text').get() # 匹配window.searchResult对应的对象内容 match = re.search(r'window\.searchResult\s*=\s*({.*?});', script, re.DOTALL) if match: js_obj_str = match.group(1) # 处理JS与JSON的语法差异:单引号转双引号,undefined替换为null json_str = js_obj_str.replace("'", '"').replace('undefined', 'null') try: search_result = json.loads(json_str) products = search_result.get('products', []) # products即为目标数据 print(products) except json.JSONDecodeError as e: print(f"JSON解析失败: {e}") else: print("未找到window.searchResult对象")
注意:如果原JS对象本身使用双引号,且没有undefined这类JSON不支持的关键字,可以跳过字符串替换步骤。
方法2:使用js2py执行JS代码(兼容复杂语法)
如果正则无法处理复杂的JS语法(比如包含函数调用、特殊字面量),可以用js2py直接运行这段脚本:
- 先安装依赖:
pip install js2py
- 代码实现:
import js2py script = response.css('[id="server-side-container"] script::text').get() # 创建JS执行上下文并运行脚本 context = js2py.EvalJs() context.execute(script) # 提取products属性 products = context.window.searchResult.get('products', []) print(products)
方法3:使用PyMiniRacer轻量JS引擎(性能更优)
PyMiniRacer是一款轻量级的JS运行时,执行速度比js2py更快,适合高频解析场景:
- 安装依赖:
pip install py-mini-racer
- 代码实现:
from py_mini_racer import py_mini_racer script = response.css('[id="server-side-container"] script::text').get() ctx = py_mini_racer.MiniRacer() ctx.eval(script) # 获取目标数据 search_result = ctx.eval('window.searchResult') products = search_result.get('products', []) print(products)
内容的提问来源于stack exchange,提问作者Tanhaeirad
相关产品推荐
相关产品推荐

