python 解析html<script>标签内变量内容
最近在试用scrapy爬取网站数据发现部分图表是通过异步生成的,scrapy获取到的html页面内只有一个空标签。因此只能查找其原数据,还好通过翻查实例化表格的js文件就追溯到了。但是数据在原html页面内的script标签内以js直接定义,如下图:不能直接通过xpath获取,而且是普通object和array两种格式,通过直接字符串操作肯定不够优雅。因此需要绕一下:
import js2xml
import json
import xmltodict
from lxml.etree import tostring
import xmldict_simplify #下文定义的方法
#中略...
dataName ="forecast_1h"
scripts = response.xpath('//script/text()').extract()
#获取特定script标签的内容,不包含标签本身
script =list(filter(lambda x: (dataName in x ),scripts))[0]
#script内容 → xml
xml = js2xml.parse(script,encoding='utf-8',debug=False)
如果这一步直接xml转json的话,会得到这样的数据即带数据类型的json数据,但是这样的dict自然是不好用的,因此定义个方法处理下
def typeParse(xmlobj):
keys = list(xmlobj.keys())
if(len(keys)>1):
#引用类型嵌套调用
if(keys[1]=="array"):
return {xmlobj[keys[0]]:list(map(lambda x:typeParse(x),xmlobj["array"]["object"]))}
elif(keys[1]=="object"):
return {xmlobj[keys[0]]:typeParse(xmlobj["object"])}
if(len(keys)==1 and keys[0]=="property"):
_property = {}
for item in xmlobj["property"]:
_keys = list(item.keys())
#值类型直接输出
if(_keys[1]=="string"):
_property[item["@name"]] = item["string"]
elif(_keys[1]=="number"):
_property[item["@name"]] = item["number"]["@value"]
#引用类型继续处理
else:
_property[item["@name"]] = int(typeParse(item)[item["@name"]])
return _property
在主流程内使用
_dict = xmltodict.parse(tostring(xml))["program"]
_data = {}
if(len(_dict["var"])>0):
for item in _dict["var"]:
_simplify = xmldict_simplify.typeParse(item)
_data = dict(_data,**dict(_simplify))
得到了普通的dict和list数据{"forecast_1h": [{"time": "08", "weatherCode": "d07", "weather": "\u5c0f\u96e8", "temp": "28", "windL": "<3\u7ea7",...
"forecast_default": {"time": "11:00", "weatherBg": "weatherBg02",...
转载自:https://segmentfault.com/a/1190000023591993