Python-如何从脚本中的变量内部提取数据?

时间:2018-12-09 22:15:24

标签: python beautifulsoup

我是Python的新手,我正尝试使用BeautifulSoup从脚本中定义的变量中提取一些数据。

data = soup.find_all('script', type='text/javascript')
print(data[0])

<script type="text/javascript">
  var myvar = {
    productid: "101",
    productname: "Abc",
  };
</script>

您知道从myvar变量中提取“ productid”和“ productname”的简单方法吗?

3 个答案:

答案 0 :(得分:1)

有两种方法。简单,错误。还是不太容易,但是正确。

我不会向您推荐简单的方法。正确的方法是使用Javascript解析器。对于现代Javascript,esprima是一个不错的选择。有一个interactive online demo,它也可以作为Python module使用。

... datetime
    01:00:00
    03:00:00

在这个简单的脚本中,没有太多事情发生。原始令牌列表足以获取所需的值。看起来像这样:

import esprima

# script body as extracted from beautifulsoup
script_text = """
  var myvar = {
    productid: "101",
    productname: "Abc",
  };
""";

tokens = esprima.tokenize(script_text)

遍历列表并选择所需的值。

[
    {
        "type": "Keyword",
        "value": "var"
    },
    {
        "type": "Identifier",
        "value": "myvar"
    },
    {
        "type": "Punctuator",
        "value": "="
    },
    {
        "type": "Punctuator",
        "value": "{"
    },
    {
        "type": "Identifier",
        "value": "productid"
    },
    {
        "type": "Punctuator",
        "value": ":"
    },
    {
        "type": "String",
        "value": "\"101\""
    },
    {
        "type": "Punctuator",
        "value": ","
    },
    {
        "type": "Identifier",
        "value": "productname"
    },
    {
        "type": "Punctuator",
        "value": ":"
    },
    {
        "type": "String",
        "value": "\"Abc\""
    },
    {
        "type": "Punctuator",
        "value": ","
    },
    {
        "type": "Punctuator",
        "value": "}"
    },
    {
        "type": "Punctuator",
        "value": ";"
    }
]

对于更复杂的情况,可能有必要将脚本解析成一棵树并沿着树走动。

token_iterator = iter(tokens)

for token in token_iterator:
    if token["type"] == "Identifier" and token["value"] == "productname":
        # the token after the next must be the one that holds the associated value
        value_token = next(next(token_iterator))
        productname = value_token["value"]

这棵树比较复杂(您可以在交互式页面上查看),但作为交换,它会携带普通令牌列表中缺少的所有上下文信息。然后,您将使用访问者模式将这棵树移至特定位置。如果您有兴趣,Python软件包中有一个example how to use the visitor pattern

答案 1 :(得分:0)

解析

from bs4 import BeautifulSoup

script_data='''
<script type="text/javascript">
  var myvar = {
    productid: "101",
    productname: "Abc",
  };
</script>
'''
soup = BeautifulSoup(script_data)

soup.script.stringscript标记内的数据保存为字符串。您可以在字符串上使用split来获取位置数据:

soup.script.string.split()
Output:
['var',
 'myvar',
 '=',
 '{',
 'productid:',
 '"101",',
 'productname:',
 '"Abc",',
 '};']

product_id:

soup.script.string.split()[5].split('"')[1]
Output:
'101'

产品名称:

soup.script.string.split()[7].split('"')[1]
Output:
'Abc'

答案 2 :(得分:0)

为简单起见,我将使用正则表达式

import re

.....
data = soup.find_all('script', type='text/javascript')
productid = re.search(r'productid:\s*"(.*?)"', data[0].text).group(1)
print(productid)