HLTV赛事结果爬虫仅抓取首个results-sublist问题求助
解决HLTV赛事结果抓取时无法获取全部results-sublist的问题
问题原因分析
静态请求(urllib+BeautifulSoup)场景
- 误用选择器方法:如果代码里用了
find()而非find_all(),只会返回第一个匹配的results-sublist元素,直接导致后续内容缺失。 - 动态渲染限制:HLTV部分赛事列表是通过前端JS动态加载的,直接请求分页URL返回的静态HTML里只包含部分内容,其余列表需要JS执行后才会渲染。
- 反爬拦截:未设置合规的请求头(比如User-Agent),服务器返回不完整的页面内容。
Selenium场景
- 未等待页面渲染:切换分页后立刻执行抓取操作,此时
results-sublist元素还未加载完毕。 - 自动化检测:HLTV识别出Selenium的特征(比如默认的ChromeDriver标识),限制了内容加载。
- 分页操作逻辑错误:直接修改URL后未等待页面刷新,或点击分页按钮后未等待AJAX请求完成就开始抓取。
解决方案
一、修复静态请求(urllib+BeautifulSoup)方案
- 修正选择器方法
确保使用find_all()获取所有匹配的results-sublist元素:
from urllib.request import Request, urlopen from bs4 import BeautifulSoup url = "https://hltv.org/results?offset=0" # 模拟浏览器请求头,避免反爬拦截 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" } req = Request(url, headers=headers) html = urlopen(req).read() soup = BeautifulSoup(html, "html.parser") # 用find_all获取所有results-sublist sublists = soup.find_all("div", class_="results-sublist") for sublist in sublists: results = sublist.find_all("div", class_="result-con") print(f"当前子列表包含{len(results)}条赛事结果")
- 处理动态渲染内容
如果静态HTML确实不包含完整内容,改用支持JS渲染的requests-html库:
from requests_html import HTMLSession session = HTMLSession() url = "https://hltv.org/results?offset=0" 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" } r = session.get(url, headers=headers) r.html.render() # 执行JS渲染页面 sublists = r.html.find(".results-sublist") for sublist in sublists: results = sublist.find(".result-con") print(f"当前子列表包含{len(results)}条赛事结果")
- 优化反爬应对
循环抓取分页时添加随机延迟(比如time.sleep(random.uniform(1,3))),避免请求频率过高触发拦截。
二、修复Selenium方案
- 等待元素加载完成
使用显式等待替代强制等待,确保元素加载后再抓取:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("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") # 隐藏Selenium自动化标识 options.add_argument("--disable-blink-features=AutomationControlled") driver = webdriver.Chrome(options=options) # 示例分页偏移,可根据需求调整 for offset in [0, 100, 200]: url = f"https://hltv.org/results?offset={offset}" driver.get(url) # 等待所有results-sublist加载完成,最长等待10秒 WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CLASS_NAME, "results-sublist")) ) sublists = driver.find_elements(By.CLASS_NAME, "results-sublist") print(f"当前页面共{len(sublists)}个results-sublist") for sublist in sublists: results = sublist.find_elements(By.CLASS_NAME, "result-con") print(f"子列表包含{len(results)}条结果") driver.quit()
- 规避自动化检测
使用undetected-chromedriver库替代原生Selenium,绕过HLTV的检测:
from undetected_chromedriver import Chrome, ChromeOptions options = ChromeOptions() options.add_argument("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") driver = Chrome(options=options) # 后续抓取逻辑同上述Selenium代码
- 验证分页操作
如果是通过点击分页按钮切换页面,需等待URL变化或元素重新加载后再执行抓取,比如添加等待URL更新的逻辑。
内容的提问来源于stack exchange,提问作者BreeZeriNooo
相关产品推荐
相关产品推荐

