Python爬虫获取MLB赛程数据异常:parsed_data.csv无有效内容
问题描述
- 需求:从指定页面爬取2023年MLB赛程及比分数据,生成可直接导入Google Sheets的CSV文件
- 异常:生成的
parsed_data.csv仅包含表头,无任何比赛数据 - 提供了多段Python爬虫代码,包含请求页面、解析、数据处理逻辑,请求排查并修复
问题根源
- 动态Div ID失效:原代码依赖硬编码的
div_655919807定位赛程区域,该ID为页面动态生成,页面更新后会直接导致数据提取失败 - 冗余的中间处理步骤:将Div文本按换行拆分存入CSV后再逐行解析,拆分后的单行文本不包含完整比赛结构,无法提取有效数据
- 比赛数据提取逻辑错误:使用
find_previous链式查找球队和比分的逻辑混乱,匹配规则和查找方向均不正确,无法获取有效字段
修复后的完整代码
import requests from bs4 import BeautifulSoup import pandas as pd import csv # 爬取并解析MLB 2023赛程数据 url = "https://www.baseball-reference.com/leagues/majors/2023-schedule.shtml" response = requests.get(url) if response.status_code != 200: print(f"请求失败,状态码:{response.status_code}") exit() soup = BeautifulSoup(response.text, 'html.parser') # 使用稳定的class选择器定位赛程容器,避免动态ID问题 schedule_container = soup.find('div', class_='section_content') if not schedule_container: print("未找到赛程内容区域") exit() parsed_data = [] # 遍历所有日期分组 date_sections = schedule_container.find_all('h3') for date_section in date_sections: # 提取日期文本 game_date = date_section.get_text(strip=True) # 获取当前日期对应的比赛表格 game_table = date_section.find_next_sibling('table') # 遍历表格中的比赛行(跳过表头行) game_rows = game_table.find_all('tr', class_=lambda c: c != 'thead') for row in game_rows: # 跳过无数据的空行 if not row.find('td'): continue # 通过语义化的data-stat属性提取字段,避免文本匹配误差 away_team = row.find('td', attrs={'data-stat': 'away_team'}).get_text(strip=True) away_score = row.find('td', attrs={'data-stat': 'away_score'}).get_text(strip=True) home_team = row.find('td', attrs={'data-stat': 'home_team'}).get_text(strip=True) home_score = row.find('td', attrs={'data-stat': 'home_score'}).get_text(strip=True) parsed_data.append({ 'Date': game_date, 'Away Team': away_team, 'Away Score': away_score, 'Home Team': home_team, 'Home Score': home_score }) # 生成规整的CSV文件,可直接导入Google Sheets df = pd.DataFrame(parsed_data) df.to_csv('parsed_data.csv', index=False) print(f"成功导出{len(df)}条比赛数据到parsed_data.csv") # 修复pine-sports数据爬取(添加反爬头部) url_pine = 'https://www.pine-sports.com/stats/props/MLB/' 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' } response_pine = requests.get(url_pine, headers=headers) soup_pine = BeautifulSoup(response_pine.content, 'html.parser') table = soup_pine.find('table', {'id': 'myTable'}) if table: headers = [th.text.strip() for th in table.find_all('th')] rows = [] for tr in table.find_all('tr'): row = [td.text.strip() for td in tr.find_all('td')] if row: rows.append(row) with open('mlb_stats.csv', 'w', newline='', encoding='utf-8') as file: writer = csv.writer(file) writer.writerow(headers) writer.writerows(rows) print("pine-sports数据导出成功") else: print("未找到pine-sports的统计表格")
修复说明
- 替换动态ID为稳定选择器:使用
class_='section_content'定位赛程容器,避免页面动态ID变化导致的定位失败 - 简化数据提取流程:跳过冗余的中间文件生成步骤,直接从页面的日期分组和比赛表格提取数据,逻辑更高效可靠
- 语义化字段提取:利用页面表格td标签自带的
data-stat属性提取球队和比分,完全避免文本匹配的混乱和误差 - 添加反爬支持:针对pine-sports的请求添加User-Agent头部,降低被网站拦截的概率
- 生成标准CSV:输出的CSV格式规整,表头与数据一一对应,可直接导入Google Sheets使用
内容的提问来源于stack exchange,提问作者TooTallDerr
相关产品推荐
相关产品推荐

