Извлечение данных из HTML

1

Я пытаюсь очистить сайт. Я смог получить содержимое на веб-сайте в строку/файл.

Теперь я хотел бы найти определенную строку, которая имеет что-то вроде:

<li><span class="abc">Key 1:</span>&nbsp;<span class="aom_pb">Value 1</span></li>

Существует только один ключ 1: на веб-сайте, и мне нужно получить значение 1. Какой лучший способ сделать это. Если его через регулярное выражение, вы можете помочь мне с тем, как он должен выглядеть. Я не использовал Regex много.

С уважением, AMM

Теги:
scrape

4 ответа

5

Вместо того, чтобы использовать регулярное выражение, я бы начал с того, что BeautifulSoup проанализировал html.

Затем вы можете использовать встроенные функции поиска для поиска классов "abc" и "aom_pb".

import BeautifulSoup

soup = BeautifulSoup.BeautifulSoup(downloaded_str)
key = soup.find('span', {'class': 'abc'}).text
value = soup.find('span', {'class': 'aom_pb'}).text 

Если тег класса не уникален, просто переверните их, пока не найдете правильный:

for li in soup.findAll('li'):
    if li.find('span', attrs={'class': 'abc'}, text='Key 1:'):
        print li.find('span', {'class': 'aom_pb'}).text

Ключевым моментом является то, чтобы парсер превратил это в проблему навигации дерева, а не из-за плохо определенной проблемы текстового поиска.

BeautifulSoup - это простой, чистый файл python, который легко добавить в вашу настройку. Это популярный выбор. Более сложные альтернативы включают html5lib и lxml. Стандартная библиотека включает HTMLParser, но она несколько упрощена и не очень хорошо обрабатывает плохо сформированный HTML.

Подход регулярного выражения немного хрупкий, но вы можете попробовать что-то вроде этого (в зависимости от того, как обычно выкладываются данные):

>>> s = '''<li><span class="abc">Key 1:</span>&nbsp;<span class="aom_pb">Value 1</span></li>'''
>>> re.search(r'Key 1:.*?(Value .*?)<', s).group(1)
'Value 1'
  • 0
    что если abc не уникален? или в этом отношении даже 'aom_pb' не уникален. Одной вещью, которая гарантированно будет уникальной в html, является текст ключа 1, а значение 1 - следующий элемент span.
  • 0
    Благодарю. это проясняет
Показать ещё 2 комментария
4

Вы должны использовать парсер, такой как lxml для извлечения данных из HTML. Использование регулярных выражений для такой задачи - это "Плохая идея" tm.

Lxml позволяет использовать выражения XPath для выбора элементов, и в этом случае соответствующий "ключевой" диапазон можно выбрать с помощью выражения //span[@class='abc' and text()='Key 1:']. Это выражение просто ищет все дерево элементов span с классами abc и содержит точный текст. Key 1:

Затем вы можете использовать .getnext() для элемента, чтобы получить следующий элемент, который содержит .getnext() вам данные.

Вот как это можно сделать в полном объеме:

import lxml.html as lh

html = """
<html>
<head>
    <title>Test</title>
</head>
<body>
<ul>
    <li><span class="abc">Key 3:</span>&nbsp;<span class="aom_pb">Mango</span></li>
    <li><span class="abc">Key 1:</span>&nbsp;<span class="aom_pb">Pineapple</span></li>
    <li><span class="abc">Key 2:</span>&nbsp;<span class="aom_pb">Apple</span></li>
    <li><span class="abc">Key 7:</span>&nbsp;<span class="aom_pb">Peach</span></li>
</ul>
</body>
</html>
"""

tree = lh.fromstring(html)

for key_span in tree.xpath("//span[@class='abc' and text()='Key 1:']"):
    print key_span.getnext().text

Результат:

Pineapple

2

Вы не должны использовать регулярные выражения для синтаксического анализа HTML. Там есть модуль парсера HTML для python, точно названный HTMLParser. http://docs.python.org/library/htmlparser.html

  • 0
    Спасибо, Дэн, в Htmlparser, есть ли способ поиска по ключу 1, а затем перейти к следующему элементу, который в основном будет иметь значение 1?
1

Другой подход, использующий BeautifulSoup: цикл над элементами <li> и проверка <span> s внутри них.

import BeautifulSoup

downloaded_str='''
<li><span class="abc">Key 0:</span>&nbsp;<span class="aom_pb">Value 1</span></li>
<li><span class="abc">Key 1:</span>&nbsp;<span class="aom_pb">Value 1</span></li>
<li><span class="abc">Key 2:</span>&nbsp;<span class="aom_pb">Value 1</span></li>
'''

soup = BeautifulSoup.BeautifulSoup(downloaded_str)
for li in soup.findAll('li'):
    span = li.find('span', {'class': 'abc'}, recursive=False)
    if span and span.text == 'Key 1:':
        return li.find('span', {'class': 'aom_pb'}, recursive=False).text

Ещё вопросы

Сообщество Overcoder
Наверх
Меню