我已经阅读了大量有关同一问题的关于stackoverflow的文章,但没有人为我工作。
标签我需要选择:
<p class="line">Actors: <a href="somelink">Actor 1</a></p>
该页面中包含p
个class="line"
标记,因此我尝试通过查找包含字符串&#34; Actors:&#34;:
data.find('p', attrs={'class':'line'}, text=re.compile(r'^Actors: $'))
这不匹配任何东西。什么是正确的语法?
答案 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=None
与p
标记匹配的原因是:
当我们在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的类吗?
希望有效。在我的考试中做了。