首页 > 作文

JavaScript中的JSON转为Python可读取

更新时间:2023-04-04 18:29:09 阅读: 评论:0

目录
创作背景问题再现解决办法形参与实参对应关系格式化 json给键加上双引号识别且替换值总代码不足

创作背景

最近本菜鸡在爬一个网站的时候,意外发现所需 json 数据在页面前端,但是不易提取,写下此篇博客以记录解决方案。

问题再现

数据是通过 js 代码传递的,大致格式(仅 作举例说明 ,方便查看层次,实际 在同一行 )如下:

function (a, b, c, d){    return {        title: a,        data: [            {            data: b        },            {                data: c            },            {                data: d            }    ]    }}('title', 2, 3, 4)

我要提取的是整个 json 格式的数据。

如果要直接提取,可以使用

re.findall('return (\{.*?\})\}\(', content)

得到结果,但如果要解析数据,会报以下的错:

意思是:键值对中的键需要被双引号包含

所以我们要完成任务的话,需要解决以下问题:

键需要用 "" 包含。需要将形式参数 a, b, c, d 转化为实际参数 "title", 2, 3, 4

解决办法

形参与实参的对应关系容易解决,所以先解决这个问题。

形参与实参对应关系

可以使用以下代码得到 形式参数

''.join(re.findall('function\((.*?)\)\{', content)).split(',')

使用下述代码获得 实际参数

''.join(re.findall('}\((.*?)\)', content)).split(',')

因为 形式参数实际参数个数 一样,所以可以根据 列表索引 建立对应关系,使用 np.c_ 可以进行 列表横向合并

代码如下:

# 获得实际参数argument = ''.join(re.findall('}\((.*?)\)', content)).split(',')# 获得形式参数formal_parameter = ''.join(re.findall('function\((.*?)\)\{', content)).split(',')# 建立对应关系mapping = pd.dataframe(np.c_[formal_parameter, argument])# 以形参作为索引mapping.t_index(0, drop=true, inplace=true)

结果如下:

格式化 json

要解决这个问题,我们需要先提取出 json 字符串,代码如下:

string = ''.join(re.findall('return (\{.*?\})\}\(', content))

结果如下:

然后,我们需要有个思路,如下:

{ , 后边,: 之前的部分是 ,需要加上双引号。:[{ 后边,], 之前的部分都是 ,需要识别且替换。

给键乐小米加上双引号

因为涉及到 插入元素python 中只有 列表 能担此重任,所以我们需要先 将字符串转为列表 ,代码如下:

string = list(''.join(re.findall('return (\{.*?\})\}\(', content)))

然后,我们需要设置一个变量,当识别出是 的时候就 1 ,否则为 0

key_flag = 0

如果我们按照上文中的规则识别出 ,就要从当前位开始,一直到 : 之前的这部分都用 双引号 包含。

还有些特殊情况,比如

嵌套字典 ,比如一个列表中值均为字典 。空字典{ 后边是 }

考虑到特殊情况,代码如下:

index = 0while true:    # 如果索引超出范围,就跳出循环    if index >= len(string):        break    # 给键加双引号    if key_flag:        # 在当前位插入一个双引号        string.inrt(index, '"')        index += 1        # 循环读取         while true:            # 直到出现 ":",循环读取的部分为 键            # 在 键 的最后添加一个双引号            if string[index] == ':':                string.inrt(index, '"')                # 重置 key_flag                key_flag = 0                # 终止循环                break            # 读取下一如何打开命令行窗口位            index += 1    # 当前字符为 "{" 或 ",",则后边的为 键    if string[index] in '{,':        key_flag = 1        # 嵌套时,则将索引移向下一位        if string[index+1] in '{':            index += 1        # 如果为空字典,则重置 key_value        if string[index+1] in '}':            key_flag = 0        index += 1

结果如下(因篇幅限制,代码无法截全):

可以看到,已经将所有的键用双引号包含。

识别且替换值

这一部分还是小有难度的。

首先,和上边一样,我们还是需要一个变量,记录当前识别 的状态,1 代表识别出来了,0 代表没有。

value_flag = 0

不过也是有特殊情况:

值已经是字符串 ,但 字符串中有 :值是 js 语句 ,不过其不是我们要提取的数据。

考虑到特殊情况,代码如下:

while true:        if index >= len(string):        break    # 检测到 值    if value_flag:        # 取出当前字符        value = string.pop(index)        # 如果字符是数字、"[" 和 "{" 或者已经是字符串        if value in '"1234567890[{' or is_value:2013国五条            value_flag = 0            string.inrt(index, value)            index += is_value        # 不符合上述情况        el:            # 循环取出 值 字符串            while true:                # 如果为 "," 或 "}",则代表已取完                if string[index] in ',}':                    break                value += string.pop(index)            # 如果 值 字符串在对应关系中,就替换            if value in mapping.index:                # 因为是在当前位不断插入,所以要将数据反向                trans = mapping.异冢loc[value][::-1]            # 如果不在,则直接替换成空字符串            el:                trans = '""'            # 计算索引要移动几位            length = len(trans)            # 插入对应的数据            for c in trans:                string.inrt(index, c)            # 索引移动            index += length                        value_flag = 0                        continue    # 如果识别到 ":" 且该 ":" 不在值字符串中    if string[index] in ':' and not is_value:        value_flag = 1        # 如果是值是字符串,则设置 is_value        if string[index+1] in '"':            is_value = 1    # 识别值字符串结束,并重置 is_value    elif string[index] in '"' and is_value:        is_value = 0    index += 1

结果如下:

可以看到,转换的还是挺成功的。

总代码

content = '''function(a,b,c,d){return {title:a,data:[{data:b},{data:c},{data:d}]}}("title",2,3,4)'''string = list(''.join(re.findall('return (\{.*?\})\}\(', content)))is_value = 0key_flag = 0value_flag = 0index = 0while true:        if index >= len(string):        break        if key_flag:                string.inrt(index, '"')        index += 1                while true:            if string[index] == ':':                string.inrt(index, '"')                key_flag = 0                break            index += 1                elif value_flag:                value = string.pop(index)                if value in '"1234567890[{' or is_value:            value_flag = 0            string.inrt(index, value)            index += is_value        el:                        storage = index                        while true:                if string[index] in ',}':                    break                value += string.pop(index)                        if value in mapping.index:                trans = mapping.loc[value][::-1]            el:                trans = '""'            length = len(trans)            for c in trans:                string.inrt(index, c)            index += length                        value_flag = 买入套期保值0                        continue        if string[index] in '{,':        key_flag = 1        if string[index+1] in '{':            index += 1        if string[index+1] in '}':            key_flag = 0    elif string[index] in ':' and not is_value:        value_flag = 1        if string[index+1] in '"':            is_value = 1        elif string[index] in '"' and is_value:        is_value = 0    index += 1    ''.join(string)

结果如下:

这时候就可以使用 json.loads 来提取数据了。

结果如下:

不足

其实上述代码是有不足的地方的。因为这段 js 代码是特殊的,是 在一行 ,且 没有多余的空格

不过也是有解决办法的:

如果 有空格 怎么办? —> 在 提取形参使用形参转换实参 时使用 strip 去除两侧的空格即可。

代码不在一行 怎么办? —> 使用 .replace('\t', '').replace('\n', '') 去除 换行符制表符 ,然后再进行格式化工作。

其实如果只是 代码不在一行 的问题的话,js.loads 会帮我们去除 \n 之类的,直接提取重要部分。

不过如果要使用我的代码的话,目前只支持 在一行js 代码。

还有就是有些 将键值对的值设置成逻辑运算式 ,比如 a || "" 这种,也不太好提取,还得根据问题调整。

这些都只是思路,大家可以自行尝试,如果有问题也及时提出来。

到此这篇关于javascript中的json转为python可读取的文章就介绍到这了,更多相关javascript json转为python内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 18:29:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/cf7207c0c7794c0d4005cc0805076699.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:JavaScript中的JSON转为Python可读取.doc

本文 PDF 下载地址:JavaScript中的JSON转为Python可读取.pdf

标签:代码   字符串   双引号   参数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图