基于文本提取div属性:Python3.6+bs4获取portfolio_no遇输出None问题
解决方法:提取指定文本对应的div属性值
我明白你遇到的问题了——用text='VBHIKE324'筛选div时找不到对应的元素,输出None,没法拿到目标的portfolio_no值。这大概率是因为BeautifulSoup的text参数是精确匹配,如果标签文本带有看不见的空白字符(比如换行、空格),或者匹配逻辑的小细节没注意到,就会匹配失败。
这里有几种可靠的解决方式:
方法1:使用lambda表达式灵活匹配文本(推荐)
通过lambda表达式先去除文本前后的空白,再和目标字符串比较,能避免空白字符的干扰:
from bs4 import BeautifulSoup html = '''<div class="Portfolio" portfolio_no="345">VBHIKE324</div> <div class="Portfolio" portfolio_no="567">SCHF54TYS</div>''' soup = BeautifulSoup(html, 'html.parser') # 筛选文本匹配的div,提取portfolio_no属性 target_div = soup.find('div', class_='Portfolio', text=lambda t: t and t.strip() == 'VBHIKE324') if target_div: print(target_div['portfolio_no']) # 输出:345
这里的lambda t: t and t.strip() == 'VBHIKE324'会先判断文本是否存在(避免None报错),再去除空白后比较,兼容性更强。
方法2:先获取所有目标div,再遍历筛选
如果觉得lambda不够直观,也可以先拿到所有class为Portfolio的div,再逐个检查文本:
from bs4 import BeautifulSoup html = '''<div class="Portfolio" portfolio_no="345">VBHIKE324</div> <div class="Portfolio" portfolio_no="567">SCHF54TYS</div>''' soup = BeautifulSoup(html, 'html.parser') for div in soup.find_all('div', class_='Portfolio'): # 使用get_text(strip=True)去除文本前后空白 if div.get_text(strip=True) == 'VBHIKE324': print(div['portfolio_no']) # 输出:345
get_text(strip=True)会自动去掉文本前后的换行、空格等空白字符,确保匹配准确。
为什么你的原代码会失败?
你的原代码find_all('div',class_='Portfolio', text='VBHIKE324')用了精确文本匹配,如果HTML里的VBHIKE324前后有任何空白(哪怕是你看不到的换行),就会匹配失败。比如如果实际HTML是:
<div class="Portfolio" portfolio_no="345"> VBHIKE324 </div>
这种情况下,文本实际是\n VBHIKE324\n,和'VBHIKE324'精确匹配就会失败,这也是为什么我们需要用strip()处理的原因。
内容的提问来源于stack exchange,提问作者user3928562
相关产品推荐
相关产品推荐

