美丽的汤,按标签的内容搜索与标签

时间:2014-05-22 17:36:43

标签: python html html-parsing beautifulsoup

<th rowspan="3" style="background:#c0cfe4; width:7em">present</th>
<td>ich <a href="/wiki/mache" title="mache">mache</a></td>
<td>wir <strong class="selflink">machen</strong></td>
<th rowspan="3" style="background:#c0cfe4; width:7em">i</th>
<td>ich <a href="/wiki/mache" title="mache">mache</a></td>
<td>wir <strong class="selflink">machen</strong></td>
</tr>
<tr>
<td>du <a href="/wiki/machst" title="machst">machst</a></td>
<td>ihr <a href="/wiki/macht" title="macht">macht</a></td>
<td>du <a href="/wiki/machest" title="machest">machest</a></td>
<td>ihr <a href="/wiki/machet" title="machet">machet</a></td>
</tr>
<th colspan="6" style="background:#9999DF">future i</th>
</tr>
<tr>
<th rowspan="3" style="background:#ccccff">infinitive</th>
<td rowspan="3" colspan="2">machen werden</td>
<th rowspan="3" style="background:#ccccff">subjunctive i</th>
<td>ich werde machen</td>
<td>wir werden machen</td>
</tr>
<tr>
<td>du werdest machen</td>
<td>ihr werdet machen</td>
</tr>
<tr>
<td>er werde machen</td>
<td>sie werden machen</td>
</tr>

我正在尝试在第9行提取<td>du <a href="/wiki/machst" title="machst">machst</a></td>。当我使用soup.find_all("td" text="re.compile("^du))执行搜索时,我得到的是第24行的标记。这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

作为替代方法,您会得到next tdtextdu开头:

print next(td for td in soup.find_all("td") if td.text.startswith('du')) 

此外,您可以pass a functionfind_all()

def td_with_du(tag):
    return tag.name == 'td' and tag.text.startswith('du')

print soup.find_all(td_with_du)

演示:

>>> from bs4 import BeautifulSoup
>>> data = """
Your HTML code goes here
"""
>>> soup = BeautifulSoup(data)
>>> def td_with_du(tag):
...     return tag.name == 'td' and tag.text.startswith('du')
... 
>>> for td in soup.find_all(td_with_du):
...     print td.text
... 
du machst
du machest
du werdest machen

答案 1 :(得分:1)

问题是您无法将标记与文本和嵌套标记匹配(请参阅How can I get text out of a <dt> tag with a <span> inside?),这就是您唯一的匹配是<td>du werdest machen</td>的原因。

当标签本身包含嵌套标签时,标签对象的string属性为None。但是,正如Martijn Pieters在上面的链接中所述,.text 包含所有嵌套标签中的所有字符串,这就是为什么

>>> a = soup.find_all('td')[0]
>>> a
<td>ich <a href="/wiki/mache" title="mache">mache</a></td>
>>> print(a.string)
None
>>> print(a.text)
ich mache
>>> b = soup.find_all('td', text=re.compile('^du'))[0]
>>> b
<td>du werdest machen</td>
>>> print(b.string)
du werdest machen
>>> print(b.text)
du werdest machen

对于解决此问题的方法,你可以看到alecxe的答案。

答案 2 :(得分:0)

此解决方案假定您不仅限于对text="re.compile("^du)进行过滤。

虽然有多行文字以“du”开头,但您的数据中只有一行包含href="/wiki/machst"。因此,如果您对href属性进行过滤,则会获得“a”标记,如果您使用其中的父标记,则会获得您所追求的“td”标记:

soup.find(href="/wiki/machst").parent

如果您需要使用find_all,而不是find

for a in soup.find_all(href="/wiki/machst"):
    print a.parent

如果由于某种原因无法使用此解决方案,那么如果您能够澄清您正在运营的要求和限制将会有所帮助。