如何使用Python BeautifulSoup解析HTML提取Acharts.co榜单的歌曲与艺人名?
适配现有HTML结构的提取方案
基于你已经定位到的表格条目节点,只需要在对应节点范围内增加两类精准选择器,就能稳定拿到目标内容,不需要修改整体的请求逻辑:
- 歌曲名提取:直接定位条目内属于歌曲链接的名称节点,避免跨层级匹配错误
- 艺人列表提取:匹配所有标记为参演艺人的结构化节点,自动收集所有合作艺人,不受艺人数目多少的影响
调整后的完整可运行代码
import requests from bs4 import BeautifulSoup url = "https://acharts.co/canada_singles_top_100/2021/05" headers = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en,de;q=0.9,en-US;q=0.8,fr-FR;q=0.7,fr;q=0.6,es;q=0.5", "authority": "acharts.co", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 YaBrowser/17.6.1.749 Yowser/2.5 Safari/537.36" } response = requests.get(url, headers=headers) response.encoding = 'utf-8' soup = BeautifulSoup(response.text, 'html.parser') # 直接通过类名选中所有目标条目,省去冗余的class判断逻辑 for item in soup.select("td.cPrinciple"): # 提取歌曲名:匹配链接下标记为歌曲名称的节点 song = item.select_one('a[itemprop="url"] > span[itemprop="name"]').get_text(strip=True) # 批量提取所有参演艺人:匹配每个带byArtist标记的艺人节点下的名称 artists = [ artist_node.select_one('span[itemprop="name"]').get_text(strip=True) for artist_node in item.select('span[itemprop="byArtist"]') ] # 输出验证 print(f"歌曲名:{song}") print(f"艺人列表:{artists}")
实现逻辑说明
- 替换掉原来的全表格遍历+手动判断class的写法,直接用
td.cPrinciple选择器一步定位到所有带目标类名的节点,既减少了遍历量,也不会因为class属性顺序变动导致匹配失效。 - 提取文本时统一加
strip=True参数,自动清理文本前后的换行、多余空格,拿到的内容不需要二次清洗。 - 艺人提取逻辑是通用适配的:不管条目里是1个独唱艺人、2个合作艺人还是更多参演者,都能完整收集成列表,不会把"and"这类连接文本误抓成艺人内容——因为选择器只锁定带
itemprop="byArtist"属性的节点,周边的普通文本不属于匹配范围。 - 针对你给出的示例HTML片段,运行后会准确输出对应内容:
- 歌曲名:Mood
- 艺人列表:['24Kgoldn', 'Iann Dior']
内容的提问来源于stack exchange,提问作者Charlie Armstead
相关产品推荐
相关产品推荐

