如何提取带类名的span标签内的href?西甲2020/21赛季阵容爬取问题
问题分析与修复方案
一、原代码中的核心问题
- 联赛URL错误:目标是爬取西甲,但原代码用了
premier-league(英超路径),导致页面内容不符,需修正为西甲对应路径。 - CSS选择器语法错误:提取球员链接时,
span[class"aufstellung-rueckennummer-name"]缺少等于号,正确写法是span[class="aufstellung-rueckennummer-name"]。 - 未初始化存储列表:代码中使用
home_test但未提前定义,会触发变量未定义报错。 - 相对URL未处理:
gameLinks收集的是相对路径,直接用requests.get请求会失败,需拼接完整域名。 - 主客队未区分:
aufstellung-box类包含主客队两个容器,原代码未区分,会导致两队数据混在一起。 - 冗余请求:第一部分循环已请求比赛日页面,第二部分重复请求,浪费资源。
二、修正后的完整代码
import requests from bs4 import BeautifulSoup import re # 初始化存储数据的列表 game_links = [] home_lineups = [] away_lineups = [] # 第一步:获取所有比赛日的比赛链接(修正URL并优化请求逻辑) base_url = "https://www.transfermarkt.de" for gameday in range(1, 39): # 修正联赛路径为西甲,避免爬取英超页面 url = f"{base_url}/laliga/spieltag/wettbewerb/ES1/plus/?saison_id=2020&spieltag={gameday}" response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}) soup = BeautifulSoup(response.content, 'html.parser') # 提取所有比赛详情页链接 match_links = soup.find_all("a", class_="liveLink", href=re.compile("spielbericht")) for link in match_links: # 拼接完整URL full_link = base_url + link.get("href") game_links.append(full_link) # 第二步:遍历每个比赛页面,提取主客队球员数据 for match_url in game_links: response = requests.get(match_url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}) soup = BeautifulSoup(response.content, 'html.parser') # 获取主客队阵容容器(第一个是主队,第二个是客队) lineup_boxes = soup.find_all("div", class_="large-6 columns aufstellung-box") if len(lineup_boxes) != 2: continue # 跳过数据异常的页面 # 提取主队球员链接和姓名 home_box = lineup_boxes[0] home_players = home_box.select('span[class="aufstellung-rueckennummer-name"] a[href]') for player in home_players: player_href = player.get("href") player_name = player.get_text(strip=True) # 从href中提取球员ID(比如从/dani-parejo/profil/spieler/59561提取59561) player_id = player_href.split("/")[-1] home_lineups.append({ "name": player_name, "id": player_id, "url": base_url + player_href }) # 提取客队球员链接和姓名 away_box = lineup_boxes[1] away_players = away_box.select('span[class="aufstellung-rueckennummer-name"] a[href]') for player in away_players: player_href = player.get("href") player_name = player.get_text(strip=True) player_id = player_href.split("/")[-1] away_lineups.append({ "name": player_name, "id": player_id, "url": base_url + player_href }) # 示例:打印前5个主队球员数据 print("主队球员示例:") for p in home_lineups[:5]: print(p) print("\n客队球员示例:") for p in away_lineups[:5]: print(p)
三、关键修复说明
- User-Agent优化:改用标准浏览器UA,降低被反爬拦截的概率。
- URL修正:将
premier-league替换为laliga,确保爬取西甲比赛页面。 - CSS选择器修复:补全class属性的等于号,正确定位到球员姓名的span标签。
- 相对URL处理:将提取的相对路径拼接上主域名,确保请求有效。
- 主客队区分:通过索引分别获取主、客队的阵容容器,避免数据混淆。
- 球员ID提取:从球员详情页的URL中拆分出唯一ID,满足需求。
- 数据结构化存储:用字典存储球员姓名、ID、详情页URL,方便后续分析。
内容的提问来源于stack exchange,提问作者Aleya
相关产品推荐
相关产品推荐

