Scrapy爬取时如何将提取的JavaScript数组转换为合法JSON
Scrapy解析JS数组变量为JSON的解决方案
问题核心
你提取到的内容是JavaScript赋值语句,不是标准JSON格式,直接调用json.loads必然失败,不符合JSON规范的点包括:
- 每行带有
datos[索引] =的赋值前缀、末尾带JS语句结束符分号;,不是纯数组结构 - 数组末尾使用了JS支持但JSON不识别的单引号空字符串
'',JSON标准仅允许双引号包裹字符串值 - Scrapy本身没有JS执行能力,无法直接运行这段赋值语句拿到变量值
方案1:正则清洗+标准库json解析(无额外依赖,性能最优)
不需要引入任何第三方JS执行库,通过简单的字符串正则清洗,把内容修正为标准JSON格式后即可直接解析,适合大规模数据爬取场景:
import re import json # raw_content为你从页面提取到的包含所有datos行的原始字符串 raw_content = """ datos[0] = ["12345","3M YELLOW CAT5E CABLE","6.81","1","A","N","N","N","N","N",0,0,0,0,0,"0","0","0","0","0","P","001-0030","12","40K8957","28396","250","Due: 30-12-1899",0.0000,1,"",'']; datos[1] = ["12346","3M GREEN CAT5E CABLE","7.81","1","A","N","N","N","N","N",0,0,0,0,0,"0","0","0","0","0","P","001-0030","12","40K8957","28396","250","Due: 30-12-1899",0.0000,1,"",'']; """ products = [] # 正则匹配等号后、分号前的数组片段 pattern = re.compile(r'=\s*(\[.*?\]);', re.S) for match in pattern.finditer(raw_content): array_str = match.group(1) # 替换不合法的单引号空串为JSON支持的双引号空串 array_str = array_str.replace(",'']", ',""]') # 直接解析为Python列表 item = json.loads(array_str) products.append(item)
方案2:正则提取+ast.literal_eval解析(容错性更强)
如果页面返回的JS数组存在更多单引号字符串这类兼容Python语法、但不符合JSON规范的内容,可以用Python标准库ast的literal_eval方法解析,不需要逐点修正格式,同时不存在安全风险:
注意:禁止直接使用内置
eval()方法解析页面爬取的不可信内容,会存在远程代码注入风险;ast.literal_eval仅会解析字符串、数字、列表、字典这类字面量结构,无安全隐患。
import re import ast raw_content = """你的原始提取字符串""" products = [] pattern = re.compile(r'=\s*(\[.*?\]);', re.S) for match in pattern.finditer(raw_content): array_str = match.group(1) # 可直接识别单引号字符串,无需额外替换 item = ast.literal_eval(array_str) products.append(item)
选型建议
- 优先选方案1,性能最高,依赖最少,完全匹配你当前的数据格式
- 如果后续页面返回的JS格式有小幅变动、存在更多单引号场景,再换方案2
- 不要为了这类简单解析需求引入PyExecJS、Selenium等重量级依赖,会大幅降低爬虫爬取效率,提升部署成本
内容的提问来源于stack exchange,提问作者ofesad
相关产品推荐
相关产品推荐

