#javascript #python #beautifulsoup
#javascript #python #beautifulsoup
Вопрос:
Я рассматривал примеры того, как это сделать, но не могу в этом разобраться. Я использую beautifulsoup для очистки некоторых данных — я могу использовать его для поиска нужных мне данных, но они содержатся в следующем блоке кода. Я пытаюсь извлечь из него информацию о временных метках. У меня такое чувство, что здесь работают регулярные выражения, но, похоже, я не могу понять это — какие-либо предложения??
<script class="code" type="text/javascript">
$(document).ready(function(){
line1 = [['2009-02-23 10 AM', 5203], ['2009-02-08 10 AM', 3898], ['2009-02-09 10 AM', 4923], ['2009-02-22 10 AM', 3682], ['2009-02-21 10 AM', 3238], ['2009-02-20 10 AM', 4648]];
options1 = {
etc other text
}
});
</script>
Ответ №1:
Вы не можете использовать BS для получения этих данных — BS работает только с HTML / XML, а не с JavaScript.
Вы должны использовать regular expressions
или стандартные строковые функции.
Редактировать:
text = '''<script class="code" type="text/javascript">
$(document).ready(function(){
line1 = [['2009-02-23 10 AM', 5203], ['2009-02-08 10 AM', 3898], ['2009-02-09 10 AM', 4923], ['2009-02-22 10 AM', 3682], ['2009-02-21 10 AM', 3238], ['2009-02-20 10 AM', 4648]];
options1 = {
etc other text
}
});
</script>'''
import re
re.findall("'([^']*)'", text)
Результат:
['2009-02-23 10 AM',
'2009-02-08 10 AM',
'2009-02-09 10 AM',
'2009-02-22 10 AM',
'2009-02-21 10 AM',
'2009-02-20 10 AM']
Комментарии:
1. да, единственное, что вам поможет сделать bs4, это настроить таргетинг на этот тип данных — однако, как только вы его найдете, вам нужно проанализировать его с помощью регулярного выражения — я считаю, что использование regex
ast.literal_eval
хорошо работает в некоторых случаях.2. Предоставленный код определенно работает — спасибо. В моем конкретном примере, поскольку я использую bs4 для обработки данных в первую очередь, результирующие данные представляют собой элемент bs4, который не работает с регулярным выражением. Итак, я преобразую результат в строку, но часть кода появляется после того, как отображаются временные метки. Как я могу ограничить его тем, что находится между ‘line1’ и ‘options1’ в исходном коде? Все, что я пытаюсь, дает пустой результат .. например, re.findall(«‘(?<=x)([^’]*)(?>= y)'», текст), где x=’line1′ и y=’options1′
3. если есть
n
, то вы можетеtext.split('n')[2].strip()
и вы получитеline1 = [...];
. Теперь вы можете использовать нарезку[8:-1]
для удаленияline1 =
, а;
затем завершить — окончательноtext.split('n')[2].strip()[8:-1]
Ответ №2:
Еще одной альтернативой использованию регулярных выражений для анализа кода javascript было бы использование анализатора JavaScript, подобного slimit
. Рабочий код:
import json
from bs4 import BeautifulSoup
from slimit import ast
from slimit.parser import Parser
from slimit.visitors import nodevisitor
data = """<script class="code" type="text/javascript">
$(document).ready(function(){
line1 = [['2009-02-23 10 AM', 5203], ['2009-02-08 10 AM', 3898], ['2009-02-09 10 AM', 4923], ['2009-02-22 10 AM', 3682], ['2009-02-21 10 AM', 3238], ['2009-02-20 10 AM', 4648]];
options1 = {};
});
</script>"""
soup = BeautifulSoup(data, "html.parser")
parser = Parser()
tree = parser.parse(soup.script.get_text())
for node in nodevisitor.visit(tree):
if isinstance(node, ast.Assign) and getattr(node.left, 'value', '') == 'line1':
values = json.loads(node.right.to_ecma().replace("'", '"').strip())
print(values)
break
Печатает список Python:
[[u'2009-02-23 10 AM', 5203], [u'2009-02-08 10 AM', 3898], [u'2009-02-09 10 AM', 4923], [u'2009-02-22 10 AM', 3682], [u'2009-02-21 10 AM', 3238], [u'2009-02-20 10 AM', 4648]]