You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环以国家为字典Key爬取Transfermarkt链接报KeyError问题

问题解决:按国家分栏存储爬取的球员链接

错误根因

  • KeyError触发原因:你声明的df是空字典,没有预先为国家名称创建对应的空列表,直接调用df[name].append()时系统找不到对应的键,自然抛出键不存在的错误。
  • 所有国家重复存储相同链接的原因:外层循环的第m次迭代,本身就在爬取第m个国家对应的球员页面,当前页面所有有效球员链接都只属于links_countries['countries'][m]这一个国家,你额外加了一层遍历所有国家名的循环,会导致每拿到一个链接就给所有国家的列表都添加一次,自然出现全字段重复的问题。

修复后的代码

import pandas as pd
import time
from bs4 import BeautifulSoup

# 原始国家链接映射表
links_countries = pd.DataFrame({'links': {0: 'https://www.transfermarkt.co.uk/spieler-statistik/wertvollstespieler/marktwertetop/plus/0/galerie/0?ausrichtung=alle&spielerposition_id=alle&altersklasse=alle&jahrgang=0&land_id=1&kontinent_id=0&yt0=Show',
  1: 'https://www.transfermarkt.co.uk/spieler-statistik/wertvollstespieler/marktwertetop/plus/0/galerie/0?ausrichtung=alle&spielerposition_id=alle&altersklasse=alle&jahrgang=0&land_id=2&kontinent_id=0&yt0=Show',
  2: 'https://www.transfermarkt.co.uk/spieler-statistik/wertvollstespieler/marktwertetop/plus/0/galerie/0?ausrichtung=alle&spielerposition_id=alle&altersklasse=alle&jahrgang=0&land_id=3&kontinent_id=0&yt0=Show'},
 'countries': {0: 'Afghanistan', 1: 'Albania', 2: 'Algeria'}})

# 初始化结果字典,预先为每个国家创建空列表,避免KeyError
final_data = {country: [] for country in links_countries['countries']}

for m in range(len(links_countries)):
    # 拿到当前爬取的国家名
    current_country = links_countries['countries'][m]
    driver.get(links_countries['links'][m])
    time.sleep(3)
    soup = BeautifulSoup(driver.page_source, 'html5lib')
    pages = soup.select("#yw2 a")
    pag = []
    for p in pages:
        pag.append(p.get_text(strip=True))
    pag = [string for string in pag if string != ""]
    pag = int(pag[-1])
    print('Page number', pag)
    href = []
    for t in pages:
        href.append(t['href'])
    href = [string for string in href if string != ""]
    base_url = "https://www.transfermarkt.co.uk" + href[0].rstrip('123456789')
    
    for num in range(1, pag+1):
        url = base_url + str(num)
        print(url)
        driver.get(url)
        time.sleep(3)
        soup = BeautifulSoup(driver.page_source, 'html5lib')
        links = soup.find('table', {'class':'items'}).find_all("a")
        for li in links:
            link = li['href'].replace("#", '')
            # 过滤出球员链接,避免添加无关链接,可根据实际页面结构调整过滤规则
            if '/spieler/' in link:
                # 仅给当前国家的列表添加链接+姓名,不要遍历所有国家
                final_data[current_country].append({
                    'name': li.get_text(strip=True),
                    'link': link
                })

# 可直接转成DataFrame输出,每列对应一个国家
result_df = pd.DataFrame(dict([ (k,pd.Series(v)) for k,v in final_data.items() ]))

核心修改说明

  • 把最终存储结构改成预先初始化好所有国家key的字典,从根源避免KeyError
  • 移除了冗余的全国家遍历逻辑,爬哪个国家的页面就把链接存到对应国家的列表下,不会出现重复存储的问题
  • 增加了球员链接和姓名的匹配存储,同时过滤掉无关的a标签链接,避免无效数据入库
  • 最后提供了转成DataFrame的逻辑,直接就能得到按国家分栏的结果

内容的提问来源于stack exchange,提问作者me.limes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 10:27:04