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

Python网页爬取脚本无结果输出问题求助

爬取国际联赛球员头像无输出问题排查与修复

问题背景

已有针对D-League球员页面的成功爬取脚本,可提取球员姓名、URL及头像地址,但适配国际联赛统计页面后,脚本无任何输出且无报错。

核心错误原因

  1. Player列选择器不匹配
    原脚本使用{'data-th': 'Player'}定位球员所在td,但国际联赛页面中,该td的data-th属性值为**"Player Name"**,导致soup.find_all('td', {'data-th': 'Player'})返回空列表,循环直接跳过,无任何数据生成。

  2. 未处理反爬拦截
    直接用requests.get()请求可能被网站识别为爬虫,返回空页面或非预期内容,导致后续解析失败。

  3. URL拼接逻辑可能错误
    国际联赛页面的球员链接可能已是完整的HTTPS URL,若强行拼接域名会生成无效地址,请求失败后无数据返回。

  4. 未做元素存在性判断
    若div_profile_box不存在,直接调用find_all('img')会触发AttributeError,但因第一步循环未执行,该错误未暴露。

修正后的代码

import requests
from bs4 import BeautifulSoup
import gspread

# 初始化Google Sheets连接
gc = gspread.service_account(filename='creds.json')
sh = gc.open_by_key('1TD4YmhfAsnSL_Fwo1lckEbnUVBQB6VyKC05ieJ7PKCw')
worksheet = sh.get_worksheet(0)

def get_links(url):
    data = []
    # 添加请求头模拟浏览器,避免反爬拦截
    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'
    }
    
    try:
        req_url = requests.get(url, headers=headers)
        req_url.raise_for_status()  # 抛出HTTP请求错误
        soup = BeautifulSoup(req_url.content, "html.parser")

        # 修正选择器:使用"Player Name"匹配td
        for td in soup.find_all('td', {'data-th': 'Player Name'}):
            a_tag = td.a
            if not a_tag:
                continue  # 跳过无链接的情况
            
            name = a_tag.text.strip()
            player_url = a_tag['href']
            
            # 处理URL:如果是相对路径则拼接域名,否则直接使用
            if not player_url.startswith('http'):
                player_url = f"https://basketball.realgm.com{player_url}"
            
            print(f"Getting {name}")

            req_player_url = requests.get(player_url, headers=headers)
            req_player_url.raise_for_status()
            soup_player = BeautifulSoup(req_player_url.content, "html.parser")

            # 检查profile-box是否存在
            div_profile_box = soup_player.find('div', {'class': 'profile-box'})
            if not div_profile_box:
                print(f"Profile box not found for {name}")
                continue
            
            img_tags = div_profile_box.find_all('img')
            for i, img_tag in enumerate(img_tags):
                image_url = img_tag.get('src', '')  # 使用get避免KeyError
                if image_url:
                    row = {"Name": name, "URL": player_url, f"Image URL {i}": image_url}
                    data.append(row)
                    
    except Exception as e:
        print(f"Error processing {url}: {str(e)}")
    
    return data

urls = [
    "https://basketball.realgm.com/international/stats/2023/Averages/Qualified/All/player/All/desc",
    "https://basketball.realgm.com/international/stats/2023/Averages/Qualified/All/minutes/All/desc/2",
    "https://basketball.realgm.com/international/stats/2023/Averages/Qualified/All/minutes/All/desc/3"
]

# 批量获取数据并写入Sheets
res = []
for url in urls:
    print(f"Processing {url}")
    data = get_links(url)
    res.extend(data)

if res:
    # 处理表头,确保所有列都包含
    headers = set()
    for row in res:
        headers.update(row.keys())
    headers = sorted(headers)
    
    # 转换为Sheets所需格式
    values = [headers]
    for row in res:
        values.append([row.get(header, "") for header in headers])
    
    worksheet.append_rows(values, value_input_option="USER_ENTERED")

关键修复点说明

  • 修正选择器:将data-th的值改为"Player Name",匹配国际联赛页面的HTML结构。
  • 添加请求头:模拟浏览器请求,降低被反爬拦截的概率。
  • URL处理逻辑:判断球员链接是否为完整URL,避免无效拼接。
  • 异常处理:捕获HTTP请求错误和元素不存在的情况,输出调试信息。
  • 元素存在性检查:对a_tag、div_profile_box等关键元素做非空判断,避免崩溃。

内容的提问来源于stack exchange,提问作者Anthony Madle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:39:21