Как извлечь данные из переменной внутри скрипта? - PullRequest
0 голосов
/ 10 декабря 2018

Я новичок в Python и пытаюсь использовать BeautifulSoup для извлечения некоторых данных из переменной, определенной в скрипте.

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

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

Знаете ли вы простой способ извлечь 'productid'и 'productname' из переменной myvar?

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Есть два пути.Легко и неправильно.Или не так просто, но правильно.

Я не собираюсь рекомендовать вам легкий путь.Правильный способ - использовать синтаксический анализатор Javascript.Для современного Javascript esprima - хороший выбор.Существует интерактивная онлайн-демонстрация , которая также доступна в виде * Python-модуля 1008 *.

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"]

В более сложных ситуациях может потребоваться анализ сценария в дереве и обход дерева.

tree = esprima.parse(script_text)

Дерево более сложное (его можно просмотреть в интерактивном режиме.страница), но в обмен он несет всю контекстную информацию, которая отсутствует в списке простых токенов.Затем вы можете использовать шаблон посетителя, чтобы пройти это дерево в определенное место.В пакете Python есть пример использования шаблона посетителя , если вам интересно.

0 голосов
/ 10 декабря 2018

Для простого способа я буду использовать Regex

import re

.....
data = soup.find_all('script', type='text/javascript')
productid = re.search(r'productid:\s*"(.*?)"', data[0].text).group(1)
print(productid)
0 голосов
/ 10 декабря 2018

Parse

from bs4 import BeautifulSoup

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

soup.script.string содержит данные внутри тега script в виде строки.Вы можете использовать split в строке для получения позиционных данных:

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

product_id:

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

product_name:

soup.script.string.split()[7].split('"')[1]
Output:
'Abc'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...