求助:使用BeautifulSoup正确抓取KCBS网站赛事全量信息
KCBS赛事爬虫字段提取修复方案
原有代码存在的问题
- URL拼接存在语法错误:换行拼接时多余的
.、错误的反斜杠转义会导致请求参数异常,接口返回内容不符合预期 - 解析逻辑拆分错误:将赛事基础信息(名称、日期)和关联信息拆成两个独立循环遍历,无法绑定同一场赛事的对应字段,极易出现数据错位
- 元素选择器过于宽泛:直接匹配所有
class="row"、class="col-md-4"的div标签,会抓取到页面中非赛事模块的同名样式元素,导致提取内容混杂、字段缺失 - 缺少基础请求头,直接请求接口有概率被反爬拦截,返回空内容或错误页面
修正后可运行代码
from bs4 import BeautifulSoup import requests 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拼接错误,移除多余字符 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/120.0.0.0 Safari/537.36", "Referer": "https://mms.kcbs.us/members/evr_search.php?org_id=KCBA" } response = requests.get(url, headers=headers) response.encoding = response.apparent_encoding soup = BeautifulSoup(response.text, features='lxml') event_list = [] # 以单个赛事卡片为最小遍历单位,从根源避免字段错位 for event_card in soup.find_all('div', class_='row'): name_tag = event_card.find('b') # 跳过非赛事模块的row容器 if not name_tag: continue event_info = {} event_info['competition_name'] = name_tag.get_text(strip=True) # 提取赛事日期 date_tag = event_card.find('i') event_info['competition_date'] = date_tag.get_text(strip=True) if date_tag else "" # 提取当前赛事卡片下所有关联信息:地址、报名入口、赛事类型、联系方式等 related_content = [] event_info['related_link'] = "" for col in event_card.find_all('div', class_='col-md-4'): col_text = col.get_text(" ", strip=True) if col_text: related_content.append(col_text) link_tag = col.find('a') if link_tag and link_tag.get('href', '').startswith('http'): event_info['related_link'] = link_tag.get('href') event_info['related_content'] = related_content event_list.append(event_info) # 打印输出提取结果 for event in event_list: print("="*60) print(f"赛事名称:{event['competition_name']}") print(f"赛事日期:{event['competition_date']}") print(f"关联详情:{' | '.join(event['related_content'])}") if event['related_link']: print(f"详情链接:{event['related_link']}")
核心优化说明
- 修复URL拼接的语法错误,补充浏览器请求头,保证接口能正常返回赛事数据
- 调整遍历逻辑,所有字段均从单个赛事的外层容器内提取,彻底解决跨赛事字段错位的问题
- 增加空标签判断,避免标签不存在时程序抛出异常中断
- 统一提取同赛事卡片下的所有文本、链接信息,不会遗漏地址、报名入口等关联内容
- 对提取的文本做空白字符清理,输出内容无多余换行、空格
内容的提问来源于stack exchange,提问作者user19341179
相关产品推荐
相关产品推荐

