如何用Beautiful Soup爬取Sofifa球员所有位置并存入CSV同一列
Sofifa球员数据爬虫多位置提取修复方案
错误原因
代码仅能提取首个位置的核心问题有两个:
- 筛选位置标签时只取了第一个带
rel="nofollow"属性的a标签,没有遍历所有对应位置标签 - 遍历位置文本时反复覆盖
positions变量,且错误使用了未调用的split方法,没有对多位置做拼接处理
修正后的完整代码
from bs4 import BeautifulSoup import requests import pandas as pd # 配置基础参数 base_url = "https://sofifa.com/players?offset=" columns = ['ID', 'Name', 'Age', 'Positions','Nationality', 'Overall', 'Potential', 'Club', 'Value', 'Wage'] data = pd.DataFrame(columns = columns) for offset in range(0, 335): url = base_url + str(offset * 60) # 加请求头避免被反爬拦截,可根据实际环境调整 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } source_code = requests.get(url, headers=headers) plain_text = source_code.text soup = BeautifulSoup(plain_text, 'html.parser') table_body = soup.find('tbody') for row in table_body.findAll('tr'): td = row.findAll('td') pid = td[0].find('img').get('id') nationality = td[1].find('img').get('title') name = td[1].find("a").get("data-tooltip") # ==== 修改位置提取逻辑开始 ==== pos_list = [] # 遍历所有带nofollow的位置a标签 for pos_a in td[1].findAll('a', {'rel': 'nofollow'}): pos_span = pos_a.find('span') if pos_span: pos_list.append(pos_span.text.strip()) # 所有位置用逗号拼接为单个字符串 positions = ','.join(pos_list) # ==== 修改位置提取逻辑结束 ==== age = td[2].text.strip() overall = td[3].text.strip() potential = td[4].text.strip() club = td[5].find('a').text.strip() value = td[6].text.strip() wage = td[7].text.strip() player_data = pd.DataFrame([[pid, name, age, positions, nationality, overall, potential, club, value, wage]], columns=columns) data = pd.concat([data, player_data], ignore_index=True) print(f"已完成第{offset}页爬取", end="\r") # 去重后导出 data = data.drop_duplicates() data.to_csv('player_data.csv', encoding='utf-8-sig', index=False)
修改说明
- 新增请求头配置,降低被网站反爬拦截的概率
- 重写位置提取逻辑:先遍历所有位置标签收集所有位置文本,再用逗号拼接为单个字符串
- 将已废弃的
DataFrame.append方法替换为官方推荐的pd.concat方法,适配新版本pandas - 导出CSV时新增
index=False参数,避免导出多余的索引列
内容的提问来源于stack exchange,提问作者Kiran Narsipur
相关产品推荐
相关产品推荐

