Я пытаюсь очистить сайт. Я смог получить содержимое на веб-сайте в строку/файл.
Теперь я хотел бы найти определенную строку, которая имеет что-то вроде:
<li><span class="abc">Key 1:</span> <span class="aom_pb">Value 1</span></li>
Существует только один ключ 1: на веб-сайте, и мне нужно получить значение 1. Какой лучший способ сделать это. Если его через регулярное выражение, вы можете помочь мне с тем, как он должен выглядеть. Я не использовал Regex много.
С уважением, AMM
Вместо того, чтобы использовать регулярное выражение, я бы начал с того, что 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> <span class="aom_pb">Value 1</span></li>'''
>>> re.search(r'Key 1:.*?(Value .*?)<', s).group(1)
'Value 1'
Вы должны использовать парсер, такой как 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> <span class="aom_pb">Mango</span></li>
<li><span class="abc">Key 1:</span> <span class="aom_pb">Pineapple</span></li>
<li><span class="abc">Key 2:</span> <span class="aom_pb">Apple</span></li>
<li><span class="abc">Key 7:</span> <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
Вы не должны использовать регулярные выражения для синтаксического анализа HTML. Там есть модуль парсера HTML для python, точно названный HTMLParser
. http://docs.python.org/library/htmlparser.html
Другой подход, использующий BeautifulSoup: цикл над элементами <li> и проверка <span> s внутри них.
import BeautifulSoup
downloaded_str='''
<li><span class="abc">Key 0:</span> <span class="aom_pb">Value 1</span></li>
<li><span class="abc">Key 1:</span> <span class="aom_pb">Value 1</span></li>
<li><span class="abc">Key 2:</span> <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