我正在尝试抓取一个网站。我已经能够将网站上的内容转换为字符串/文件。
现在,我想搜索具有以下内容的特定行:
<li><span class="abc">Key 1:</span> <span class="aom_pb">Value 1</span></li>
保证只有一个 Key 1: 在网站中,我需要获得 Value 1。最好的方法是什么。如果它通过正则表达式,你能帮我看看它的外观吗?我没有太多使用正则表达式。
问候, AMM
我不会使用正则表达式,而是先让BeautifulSoup解析 html。
然后,您可以使用内置的 find 函数来搜索“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()
在元素上使用来获取包含所需数据的以下元素。
这是一个完整的方法:
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。有一个用于 python 的 HTML 解析器模块,恰当地命名为HTMLParser
. http://docs.python.org/library/htmlparser.html
另一种使用 BeautifulSoup 的方法:遍历 <li> 元素,并检查其中的 <span>。
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