Python3中替换has_key方法:解决Python2兼容的标签属性判断问题
解决方案
没问题,我来帮你搞定Python2到Python3的适配,还有标签筛选的问题!
1. 适配Python3的判断逻辑
Python3里已经移除了字典的has_key()方法,对于BeautifulSoup的Tag对象,最优雅的方式是用它自带的has_attr()方法(这个方法在Python2和3中都兼容,可读性也更强)。修改后的函数如下:
def has_class_but_no_id(tag): # 检查标签是否有class属性,同时没有id属性 return tag.has_attr('class') and not tag.has_attr('id')
如果你更习惯直接操作属性字典,也可以写成这样(效果完全一致):
def has_class_but_no_id(tag): return 'class' in tag.attrs and 'id' not in tag.attrs
2. 从descendants列表中筛选符合条件的标签
需要注意的是,soup.descendants返回的迭代器包含所有类型的节点(比如文本节点、注释节点,甚至空白符),这些非标签节点没有属性,直接判断会报错。所以我们需要先过滤出Tag类型的元素,再应用判断条件。
方法一:基于你已有的list_of_descendants列表
先导入BeautifulSoup的Tag类,然后用列表推导式筛选:
from bs4 import Tag filtered_tags = [ tag for tag in list_of_descendants if isinstance(tag, Tag) and has_class_but_no_id(tag) ]
方法二:直接从soup.descendants迭代筛选(更高效)
如果不需要提前把所有节点存到列表里,直接迭代筛选可以节省内存,代码更简洁:
from bs4 import Tag filtered_tags = [ tag for tag in soup.descendants if isinstance(tag, Tag) and tag.has_attr('class') and not tag.has_attr('id') ]
这种方式连单独的函数都可以省略,直接把判断逻辑写在推导式里。
验证结果
你可以通过打印filtered_tags来查看筛选出的标签,或者遍历它们获取具体内容:
for tag in filtered_tags: print(tag.name, tag.get('class')) # 打印标签名和class属性值
内容的提问来源于stack exchange,提问作者Tae
相关产品推荐
相关产品推荐

