如何用BeautifulSoup精准匹配仅含指定class的div元素?
首先修正你代码里的一个明显错误:循环中{'class': 'div_class'}是硬编码字符串,不是遍历的变量div_class,这会导致每次都查找class为div_class的元素,完全不符合需求,先改成{'class': div_class}——不过这还解决不了你核心的精准匹配问题。
核心问题原因
BeautifulSoup默认的class匹配是包含匹配:只要元素的class列表里包含目标值,就会被选中。所以find('div', {'class': 'something'})会同时匹配class="something"和class="something and-something-else"的元素。
两种精准匹配的方法
方法1:使用CSS选择器排除多class元素
利用CSS选择器的:not([class*=" "])规则,排除掉class属性中包含空格的元素(也就是带有多个class的元素):
div_classes = ['xf8Pm', 'something', 'cck', 'col'] for div_class in div_classes: # 精准匹配仅含当前class的div div_cont = soup.select_one(f'div.{div_class}:not([class*=" "])') if div_cont is not None: string = div_cont.text.replace('\n', '').strip() print(string)
div.{div_class}匹配包含目标class的div,:not([class*=" "])进一步过滤掉class属性里有空格的元素,只保留仅含单个目标class的元素。
方法2:用lambda判断class列表是否严格匹配
BeautifulSoup会把元素的class属性解析为列表,仅含单个class的元素,其class列表就是[目标class]。用lambda函数可以直接判断:
div_classes = ['xf8Pm', 'something', 'cck', 'col'] for div_class in div_classes: # 检查class列表是否严格等于目标值,避免无class的元素报错 div_cont = soup.find('div', class_=lambda c: c == [div_class] if c else False) if div_cont is not None: string = div_cont.text.replace('\n', '').strip() print(string)
为什么正则匹配没生效?
你之前用re.compile(r'\bsomething\b'),正则匹配的是整个class属性字符串(比如"something and-something-else"),而这个字符串里确实存在独立的something单词,所以正则会匹配到带多个class的元素,自然达不到精准匹配的效果。
内容的提问来源于stack exchange,提问作者Argi Kara

