使用BeautifulSoup查找包含某些文本的HTML标签


69

我正在尝试获取HTML文档中包含以下文本模式的元素:#\ S {11}

<h2> this is cool #12345678901 </h2>

因此,前者将通过使用以下内容进行匹配:

soup('h2',text=re.compile(r' #\S{11}'))

结果将是这样的:

[u'blahblah #223409823523', u'thisisinteresting #293845023984']

我可以获取所有匹配的文本(请参见上面的行)。但是我希望文本的父元素匹配,因此我可以将其用作遍历文档树的起点。在这种情况下,我希望所有h2元素都返回,而不是文本匹配。

有想法吗?


3
实际上,根据BeautifulSoup文档,h2限制将被忽略:“如果使用文本,则为名称和关键字参数提供的任何值都会被忽略。”
Rabarberski 2010年

@Rabarberski不确定2010年的情况如何,但到2012年发现使用text(或string替换它)不会忽略任何其他限制
TC Proctor

Answers:


81
from BeautifulSoup import BeautifulSoup
import re

html_text = """
<h2>this is cool #12345678901</h2>
<h2>this is nothing</h2>
<h1>foo #126666678901</h1>
<h2>this is interesting #126666678901</h2>
<h2>this is blah #124445678901</h2>
"""

soup = BeautifulSoup(html_text)


for elem in soup(text=re.compile(r' #\S{11}')):
    print elem.parent

印刷品:

<h2>this is cool #12345678901</h2>
<h2>this is interesting #126666678901</h2>
<h2>this is blah #124445678901</h2>

谢谢!令人困惑的是它返回了看起来像Unicode字符串列表的内容。感谢您的帮助。
sotangochips

2
.parent太棒了!我没想过 谢谢@nosklo。+1
莫辛医师

如果您想立即迭代搜索的输出,那么for完美。其他如何进行列表理解:[elem.parent表示汤中的元素(text = re.compile(r'#\ S {11}')))
peterb

@sotangochips是的,起初它看起来像在返回一个普通的unicode字符串,但实际上是一个带有的NavigableString .parent。必须使用PyCharm的调试器来了解它不是纯字符串。
何塞托马斯腌肠

21

与其他情况相反,BeautifulSoup搜索操作BeautifulSoup.NavigableStringtext=用作标准时会提供[对象列表] BeautifulSoup.Tag。检查对象的__dict__属性以查看对您可用的属性。在这些属性中,由于BS4变化parent而受到青睐。previous

from BeautifulSoup import BeautifulSoup
from pprint import pprint
import re

html_text = """
<h2>this is cool #12345678901</h2>
<h2>this is nothing</h2>
<h2>this is interesting #126666678901</h2>
<h2>this is blah #124445678901</h2>
"""

soup = BeautifulSoup(html_text)

# Even though the OP was not looking for 'cool', it's more understandable to work with item zero.
pattern = re.compile(r'cool')

pprint(soup.find(text=pattern).__dict__)
#>> {'next': u'\n',
#>>  'nextSibling': None,
#>>  'parent': <h2>this is cool #12345678901</h2>,
#>>  'previous': <h2>this is cool #12345678901</h2>,
#>>  'previousSibling': None}

print soup.find('h2')
#>> <h2>this is cool #12345678901</h2>
print soup.find('h2', text=pattern)
#>> this is cool #12345678901
print soup.find('h2', text=pattern).parent
#>> <h2>this is cool #12345678901</h2>
print soup.find('h2', text=pattern) == soup.find('h2')
#>> False
print soup.find('h2', text=pattern) == soup.find('h2').text
#>> True
print soup.find('h2', text=pattern).parent == soup.find('h2')
#>> True

对我来说soup.find('h2', text=pattern),直接给出标签,无需致电.parent。此外,文档还指出,您可以将stringtext在以前的版本中)参数与查找标签的参数组合在一起。在这种情况下,BeautifulSoup将返回标签
raffaem

4

使用bs4(Beautiful Soup 4),OP的尝试与预期完全一样:

from bs4 import BeautifulSoup
soup = BeautifulSoup("<h2> this is cool #12345678901 </h2>")
soup('h2',text=re.compile(r' #\S{11}'))

返回[<h2> this is cool #12345678901 </h2>]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.