Python爬取Futbin数据后Pandas DataFrame为空求助排查
问题分析与解决方案
核心问题
你的脚本返回空DataFrame,本质是两个关键原因:
- 反爬拦截:Futbin会识别无浏览器标识的请求,直接返回不含球员数据的空页面/验证页面,导致找不到任何球员卡片。
- 选择器失效:即使拿到有效页面,原代码的DOM选择器和当前Futbin的页面结构不匹配,无法提取数据。
解决步骤
1. 添加请求头模拟浏览器
给requests.get带上浏览器标识(User-Agent),绕过基础反爬:
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' } response = requests.get(URL, headers=headers, timeout=TIMEOUT)
这一步是核心,没有请求头的话,你拿到的页面根本不会包含任何球员数据。
2. 验证请求有效性
先打印响应状态码和页面长度,确认拿到了有效内容:
print(response.status_code) # 正常返回200 print(len(response.content)) # 有效页面长度通常大于10000字节
如果返回403/404,说明反爬仍在拦截,可以尝试添加Accept-Language等额外请求头。
3. 更新DOM选择器(适配当前Futbin页面)
当前Futbin的页面结构已变化,原选择器无法定位元素:
- 球员卡片的容器是
<tr class="player_tr">(而非原代码的div.playercard) - 球员名字的class是
player_name(而非player_name_players_table) - 价格元素的class分平台:
pc_color(PC)、ps4_color(PS)、xbox_color(Xbox)
修改后的提取逻辑:
# 定位所有球员行 player_rows = soup.find_all('tr', {'class': 'player_tr'}) player_names = [] player_values = [] for row in player_rows: # 提取球员名字 name_elem = row.find('a', {'class': 'player_name'}) if not name_elem: continue name = name_elem.text.strip() # 提取PC平台价格(可自行替换成其他平台的class) value_elem = row.find('span', {'class': 'pc_color'}) if not value_elem: continue value_text = value_elem.text.strip().replace(',', '') # 处理非数字价格(如"---") try: value = int(value_text) except ValueError: continue player_names.append(name) player_values.append(value)
4. 完整修改后的代码
import requests from bs4 import BeautifulSoup import pandas as pd URL = 'https://www.futbin.com/players?page=1&version=all_versions' TIMEOUT = 20 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', 'Accept-Language': 'en-US,en;q=0.9' } # 发送带请求头的请求 response = requests.get(URL, headers=headers, timeout=TIMEOUT) print(f"响应状态码: {response.status_code}") soup = BeautifulSoup(response.content, 'html.parser') # 提取球员数据 player_rows = soup.find_all('tr', {'class': 'player_tr'}) player_names = [] player_values = [] for row in player_rows: name_elem = row.find('a', {'class': 'player_name'}) value_elem = row.find('span', {'class': 'pc_color'}) if not name_elem or not value_elem: continue name = name_elem.text.strip() value_text = value_elem.text.strip().replace(',', '') try: value = int(value_text) except ValueError: continue player_names.append(name) player_values.append(value) # 生成DataFrame df = pd.DataFrame({'Name': player_names, 'Value': player_values}) print(df)
额外提示
- 不要频繁请求,避免IP被封禁,可在请求之间添加
time.sleep(1) - 如果仍被拦截,尝试用
requests.Session()保持会话 - 定期检查页面结构,Futbin会更新DOM,选择器可能需要调整
内容的提问来源于stack exchange,提问作者Alvaro Balduz
相关产品推荐
相关产品推荐

