Python中bs4爬虫处理html标签的问题:如何解析带空格的属性标签?
<td class="stream-6771">
<a href="javascript:void(0);" id="vid_667" class="vh"><code style="display:none">已发送</code><i>7621</i></a>
<s></s>
</td>
dataSoup = BeautifulSoup(tr.prettify(),'lxml')
tmpStr = dataSoup.find_all("code", class_= ["code","style"])
查阅文档和看了百度别人的经验,理论上这么做是能获取到“已发送”的字符串,
是否跟 python 的版本有关系? 用的是 python3,文档似乎更新时间久了,python2 的写法不能用?
谢谢解答!
Python中bs4爬虫处理html标签的问题:如何解析带空格的属性标签?
dataSoup.find_all(“code”)
或
dataSoup.find_all(attrs={‘style’: ‘display:none’})
帖子回复:
这个问题很常见,处理带空格的属性标签(比如 <div class="foo bar">)时,BeautifulSoup 的默认查找方法 find() 或 find_all() 需要特别注意。你不能直接用完整的属性值去匹配,因为 class 属性实际上是一个多值属性,空格分隔了多个值。
核心解决方案是使用CSS选择器,或者对 class 参数进行特殊处理。
下面给你两个最直接、可运行的代码示例:
方法一:使用CSS选择器(推荐)
BeautifulSoup 支持 .select() 方法,它使用CSS选择器语法,处理多值 class 非常直观。
from bs4 import BeautifulSoup
html_doc = """
<div class="foo bar">这个div有两个class</div>
<div class="foo">这个只有一个</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# 查找 class 同时包含 "foo" 和 "bar" 的div
# CSS选择器用 . 表示class
results = soup.select('div.foo.bar')
for tag in results:
print(tag.text)
# 输出:这个div有两个class
# 查找 class 包含 "foo" 的div(无论是否有其他class)
results2 = soup.select('div.foo')
for tag in results2:
print(tag.text)
# 输出:
# 这个div有两个class
# 这个只有一个
方法二:使用 find_all 并指定 class_ 参数
find_all 的 class_ 参数(注意下划线)可以接收一个字符串、列表或正则表达式。当传入字符串时,它会匹配包含该字符串的class。
from bs4 import BeautifulSoup
html_doc = """
<div class="foo bar">这个div有两个class</div>
<div class="foo">这个只有一个</div>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# 查找 class 包含 "foo" 的div
tags = soup.find_all('div', class_='foo')
for tag in tags:
print(tag.text)
# 输出:
# 这个div有两个class
# 这个只有一个
# 如果要精确匹配多个class,可以传入一个列表
tags_exact = soup.find_all('div', class_=['foo', 'bar']) # 这匹配class为 *foo* 或 *bar* 的,不是同时包含!
print("列表匹配:", [t.text for t in tags_exact])
# 要精确匹配同时拥有 "foo" 和 "bar" 的div,用CSS选择器更简单,或者用lambda
tags_exact_all = soup.find_all('div', lambda tag: tag.get('class') == ['foo', 'bar'])
print("精确匹配:", [t.text for t in tags_exact_all])
# 输出:精确匹配: ['这个div有两个class']
总结一下:
- 想匹配包含某个class的标签:直接用
find_all(..., class_='class_name')或select('tag.class_name')。 - 想匹配同时包含多个class的标签:用CSS选择器
select('tag.class1.class2')最省事。 - 记住
tag.get('class')返回的是一个列表,包含了所有用空格分隔的class值。
一句话建议:用 .select() 的CSS选择器语法来处理带空格的class属性最清晰。
,感谢您的回复解答,find_all(“code”)可以直接取出<br><code style="display:none">已发送</code><br>
这个方法小喵是是摸索出来了,
其实帖里问的是如何直接取出“已发送”这三个中文字作为 tmpStr。。。
其实还是想知道如果换了方式,我还能明白技巧在哪里。。。<br><code class="display:none">已发送变化方式之一</code><br><class fire="display:none">已发送变化方式之二</class><br><em class="display:none">已发送变化方式之三</em><br>
尽管不一定会有这样的 HTML 代码,只是想了解一下这种空格的标签,如何直接套取 text()。。。。。
感激不尽~~~!!!
.text。。
dataSoup.find(‘code’, attrs={‘style’:‘display:none’}).text

