如何从BeautifulSoup的Tag对象中提取首个a标签的href链接
爬取需求说明
近期使用BeautifulSoup与re库做网页爬取,目标是提取页面中运动员的个人资料页链接:
- 页面内容已经处理为
<class 'bs4.element.ResultSet'>类型结果集,包含运动员姓名、对应个人资料页链接 - 用for循环遍历结果集输出单个运动员信息时,每次迭代的元素类型为
<class 'bs4.element.Tag'>
单个元素的示例结构如下:
</span>, <span class="txt-blue"> <a href="https://www.eliteprospects.com/player/70215/riley-nash">Riley Nash (F)</a> <a href="https://www.eliteprospects.com/league/wjc-18-w/team-captaincy/2021-2022">“A”</a>
需要仅提取第一个球员个人页链接https://www.eliteprospects.com/player/70215/riley-nash,排除第二个队长标识相关的链接。
之前尝试过的无效方案包括:
- 以
<a href=为起始标识、首次出现的>为结束标识,截取中间内容 - 按“首个链接在第3和第4个引号之间”的规律定位字符串
- 正则直接匹配、将Tag类型转为str类型处理,均未拿到正确结果
可行实现方案
优先使用第一种BS原生方法,不需要做类型转换,对页面结构变动的容错率最高
方案1:BeautifulSoup原生标签选择
直接调用BS内置的选择器,定位特征最明确的球员链接即可,完全避开第二个无关链接:
# 遍历ResultSet时,当前处理的单个Tag对象命名为item # 方法1:直接取txt-blue类span下的第一个a标签 first_a = item.select_one('span.txt-blue a') if first_a: player_url = first_a.get('href') # 方法2:加路径特征过滤,100%不会抓到非球员链接,适配页面结构微调场景 player_a = item.find('a', href=re.compile(r'/player/\d+')) if player_a: player_url = player_a['href']
方案2:正则匹配方案
如果需要转字符串用正则处理,不要硬数引号、找标签起止位置,直接匹配带/player/路径特征的链接即可:
item_str = str(item) match_res = re.search(r'href="(https://[^"]*?/player/\d+/[^"]+)"', item_str) if match_res: player_url = match_res.group(1)
之前字符串截取、数引号方案失效的核心原因是页面缩进、属性顺序变动时,字符位置会发生偏移,硬编码位置的逻辑容错率极低,只要页面多一个空格、多一个属性就会匹配失败。
内容的提问来源于stack exchange,提问作者Blackwidow
相关产品推荐
相关产品推荐

