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

BeautifulSoup爬取KCBS活动页时无法单独拆分提取目标字段问题

KCBS赛事爬虫字段拆分实现方案

核心问题定位

原解析逻辑失效有三个直接原因:

  • 原代码URL拼接存在笔误,evr_end参数前多了冗余的.字符,可能导致接口返回异常数据
  • 活动详情字段全部存放在class="col-md-4"的div容器内,不同字段仅通过<br>标签分隔,没有独立的HTML标签做区分,直接调用getText()会把所有字段拼接成无分隔的长文本,无法拆分
  • 部分字段没有专属class或id属性,无法直接通过标签选择器定位,需要结合文本特征做匹配

实现思路

放弃直接对容器节点取整段文本的做法,遍历详情容器的所有子节点,以<br>标签为分隔符拆分出独立的文本块,再根据每个文本块的固定特征匹配对应字段:

  • 带Prize Money:前缀的文本块对应奖金金额
  • 带Reps:前缀的文本块对应负责人员
  • 取值为全大写、属于赛事等级枚举值的文本块对应赛事等级
  • 匹配国家名称关键词的文本块对应所属国家
  • 剩余符合地址格式(含州缩写、邮编)的文本块对应举办地址

完整可运行代码

import requests
from bs4 import BeautifulSoup, Tag
from datetime import datetime
from dateutil.relativedelta import relativedelta

# 构造请求时间范围
evr_begin = datetime.now().strftime("%m/%d/%Y")
evr_end = (datetime.now() + relativedelta(months=1)).strftime("%m/%d/%Y")
# 修正原URL的拼接笔误,去掉evr_end前多余的点
url = "https://mms.kcbs.us/members/evr_search_ol_json.php?" \
      f"otype=TEXT&evr_map_type=2&org_id=KCBA&evr_begin={evr_begin}&evr_end={evr_end}&" \
      "evr_radius=50&evr_type=269&evr_region_type=1"

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)
soup = BeautifulSoup(response.text, features='lxml')

# 可根据实际遇到的赛事等级、国家值扩充关键词列表
LEVEL_KEYWORDS = {"STATE CHAMPIONSHIP", "REGIONAL", "NATIONAL", "LOCAL", "INTERNATIONAL"}
COUNTRY_KEYWORDS = {"UNITED STATES", "CANADA", "MEXICO"}

for event in soup.find_all('div', class_='row'):
    # 提取已有的标题、时间字段
    event_title = event.find('b').get_text(strip=True) if event.find('b') else ""
    event_time = event.find('i').get_text(strip=True) if event.find('i') else ""
    
    # 初始化待提取字段
    address = ""
    country = ""
    level = ""
    reps = ""
    prize = ""

    detail_div = event.find('div', class_='col-md-4')
    if detail_div:
        # 按br标签拆分独立文本块
        text_blocks = []
        current_block = []
        for child in detail_div.contents:
            if isinstance(child, Tag) and child.name == 'br':
                block_text = ''.join(current_block).strip()
                if block_text:
                    text_blocks.append(block_text)
                current_block = []
            else:
                current_block.append(str(child).strip())
        # 处理最后一个文本块
        last_block = ''.join(current_block).strip()
        if last_block:
            text_blocks.append(last_block)
        
        # 逐块匹配字段
        for block in text_blocks:
            if block.startswith("Prize Money:"):
                prize = block
            elif block.startswith("Reps:"):
                reps = block
            elif block in LEVEL_KEYWORDS:
                level = block
            elif block in COUNTRY_KEYWORDS:
                country = block
            else:
                # 剩余符合地址特征的块赋值给地址
                address = block

    # 输出结果
    print("="*50)
    print(f"活动标题:{event_title}")
    print(f"活动时间:{event_time}")
    print(f"举办地址:{address}")
    print(f"所属国家:{country}")
    print(f"赛事等级:{level}")
    print(f"负责人员:{reps}")
    print(f"奖金金额:{prize}")

适配说明

  • 代码新增了常规请求头,避免接口拦截无User-Agent的默认请求
  • 爬取过程中如果遇到未覆盖的赛事等级、国家取值,直接将对应值补充到LEVEL_KEYWORDS和COUNTRY_KEYWORDS集合即可识别
  • 当前地址字段为兜底匹配逻辑,如果后续页面出现其他非地址的冗余文本块,可根据实际文本特征新增专属判断规则调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 02:21:18