Python / BeautifulSoup - 无法匹配包含特定文字的代码

时间:2017-02-07 17:25:35

标签: python beautifulsoup

我已经阅读了大量有关同一问题的关于stackoverflow的文章,但没有人为我工作。

标签我需要选择:

<p class="line">Actors: <a href="somelink">Actor 1</a></p>

该页面中包含pclass="line"标记,因此我尝试通过查找包含字符串&#34; Actors:&#34;:

data.find('p', attrs={'class':'line'}, text=re.compile(r'^Actors: $'))

这不匹配任何东西。什么是正确的语法?

3 个答案:

答案 0 :(得分:3)

我认为不能用单个表达式来完成。

import re
from bs4 import BeautifulSoup

s="""
    <p class="line">Actors: <a href="somelink">Actor 1</a></p>
    <p class="line">Other: <a href="somelink">Stunt 0</a></p>
    <p class="line">Actors: <a href="somelink">Actor 3</a></p>
    <p class="role-line">Actors: <a href="somelink">Actor 4</a></p>
"""

soup = BeautifulSoup(s, 'html.parser')

这项工作:

soup.findAll(attrs={'class':'line'})

这也是:

soup.findAll(string=re.compile(r'^Actors'))

但两者合并不起作用,bug或不支持,我不知道:

soup.findAll(attrs={'class':'line'}, string=re.compile(r'^Actors'))

但你有其他选择。

使用set交集:

set([node.parent for node in soup.findAll(string=re.compile(r'^Actors'))]) & 
set(soup.findAll(attrs={'class':'line'}))

结果:

{<p class="line">Actors: <a href="somelink">Actor 3</a></p>,
 <p class="line">Actors: <a href="somelink">Actor 1</a></p>}

使用findParents

[node.findParents('p', class_='line') for node in \
soup.findAll(string=re.compile(r'^Actors'))]

结果:(需要一些过滤)

[[<p class="line">Actors: <a href="somelink">Actor 1</a></p>],
 [<p class="line">Actors: <a href="somelink">Actor 3</a></p>],
 []]

使用循环和条件:

for p in [node.parent for node in soup.findAll(text=re.compile(r'^Actors'))]:
    if not 'line' in p.attrs['class']:
        continue
    print(p)

结果:

<p class="line">Actors: <a href="somelink">Actor 1</a></p>
<p class="line">Actors: <a href="somelink">Actor 3</a></p>

注意:string是BeautifulSoup 4.4 +

中的新text参数

答案 1 :(得分:1)

html = '''<p class="line">Actors: <a href="somelink">Actor 1</a></p>'''
soup = bs4.BeautifulSoup(html, 'lxml')
soup.p.text

出:

'Actors: Actor 1'

p标记有多个文本字段。

soup.find('p', attrs={'class':'line'}, string=None)
soup.find('p', attrs={'class':'line'}, text=None)

出:

<p class="line">Actors: <a href="somelink">Actor 1</a></p>

text/string=Nonep标记匹配的原因是:

当我们在text/string中使用find()作为过滤条件时,它会使用p.string来获取p标记的字符串,并且p标记有多个文本字段

  

如果标签包含多个内容,则不清楚是什么   .string应该引用,所以.string被定义为None

但是你可以先找到文本,然后在文本前面找到元素:

soup.find(text='Actors: ').previous_element

在这种情况下,find()仅包含文本过滤器,它在文本编辑器中的行为类似于find

答案 2 :(得分:1)

我对此也有很多困惑!

soup.findAll('p', {'class': 'line'}, text='Actors: ')

应该归还正确的东西?我相信你也可以替换ID的类吗?

希望有效。在我的考试中做了。