Python用BeautifulSoup爬取NFL球队排名数据返回空列表排错
代码问题排查与修复
核心问题清单
- 缩进逻辑错误
你遍历球队URL的第一层for url in url_list循环,只做了请求页面和生成soup的操作,所有解析表格的代码都写在了这个循环外面,导致每次循环的soup都会被下一个球队的页面覆盖,最终只会处理最后一支球队的页面,前面31支球队的数据完全丢失。
其次table_data.append(t_row)写在了tr遍历循环的外面,每个表格只会插入最后一行tr的解析结果,其他行数据全部丢失。 - 表格解析逻辑漏洞
你用zip(tr.find_all("td"), headers)配对字段和表头,但是该网站的NFL球队数据表格第一列(通常是赛季列)用的是<th scope="row">标签而非td,会导致第一列数据丢失,字段和表头数量不匹配,最终生成的t_row是空字典。 - 反爬拦截问题
pro-football-reference设置了反爬机制,直接用默认UA的requests.get请求大概率会返回403错误或者空白页面,解析不到任何表格内容。 - 变量初始化位置错误
table_data定义在表格遍历循环内部,每次处理新表格就会清空之前的解析结果,最终只能保留最后一个表格的最后一行数据。
修正后的参考代码
import numpy as np import pandas as pd import requests from bs4 import BeautifulSoup as bs # 原有的球队索引目录代码 my_array = np.array([['crd','Arizona_Cardinals'],['atl','Atalanta_Falcons'],['rav','Baltimore_Ravens'],['buf','Buffalo_Bills'], ['car','Carolina_Panthers'],['chi','Chicago_Bears'],['cin','Cincinnati_Bengals'],['cle','Cleveland_Browns'], ['dal','Dalls_Cowboys'],['den','Denver_Broncos'],['det','Detroit_Lions'],['gnb','Green_Bay_Packers'],['htx','Houston_Texans'], ['clt','Indianapolis_Colts'],['jax','Jacksonville_Jaguars'],['kan','Kansas_City_Chiefs'],['rai','Las_Vegas_Raiders'], ['sgd','Los_Angeles_Chargers'],['ram','Los_Angeles_Rams'],['mia','Miami_Dolphins'],['min','Minnesota_Vikings'], ['nwe','New_England_Patriots'],['nor','New_Orleans_Saints'],['nyg','New_York_Giants'],['nyj','New_York_Jets'], ['phi','Philidophia_Eagles'],['pt','Pittsburgh_Steelers'],['sfo','San_Francisco_49ers'],['sea','Seattle_Seahawks'], ['tam','Tampa_Bay_Buccaneers'],['oti','Tennessee_Titans'],['was','Washington_Football_Team']]) team_list = pd.DataFrame(my_array, columns=['code','teams']) # 全局初始化存储所有数据的列表 all_data = [] # 添加请求头规避反爬 req_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } url_base = 'https://www.pro-football-reference.com/teams/' url_list = [url_base+str(i) for i in team_list['code']] for url in url_list: page = requests.get(url, headers=req_headers).text soup = bs(page, 'lxml') # 表格解析逻辑放在url循环内部 for table in soup.find_all('table'): # 提取表头 headers_col = [] for th in table.find_all('th', scope = "col"): title=th.text.strip() headers_col.append(title) # 提取每行数据 for tr in table.find_all("tr"): # 先取行首的th(赛季列),再取td row_th = tr.find_all('th', scope="row") row_td = tr.find_all("td") all_cell = row_th + row_td if len(all_cell) != len(headers_col): continue t_row = {} for cell, col_name in zip(all_cell, headers_col): t_row[col_name] = cell.text.replace('\n', '').strip() # 插入到全局数据列表 if t_row: all_data.append(t_row) # 加延时规避反爬,避免请求过快被封 import time time.sleep(2) # 最后转DataFrame查看结果 result_df = pd.DataFrame(all_data) print(result_df)
内容的提问来源于stack exchange,提问作者Yishu_D
相关产品推荐
相关产品推荐

