Epic Games商店网页爬取遇Cloudflare安全验证问题求助
问题分析与解决方案
为什么浏览器和代码获取的HTML不一致?
这是正常现象。浏览器访问页面时会自动执行JavaScript代码,完成Cloudflare的人机验证流程,最终加载出目标页面内容;而requests库仅发送纯HTTP请求,不会执行任何JS,所以拿到的是Cloudflare用来拦截非浏览器请求的验证页面,自然和浏览器看到的HTML不一样。
绕过Cloudflare验证的可行方法
1. 使用支持JS渲染的浏览器自动化工具
这类工具模拟真实浏览器行为,能自动执行JS、处理验证流程,推荐用Playwright(比Selenium更轻量现代):
- 先安装依赖:
pip install playwright playwright install chromium - 示例代码:
如果遇到滑块之类的手动验证,把from playwright.sync_api import sync_playwright from bs4 import BeautifulSoup with sync_playwright() as p: # 启动无头浏览器(设为False可看到浏览器窗口,方便手动过验证) browser = p.chromium.launch(headless=True) page = browser.new_page() # 模拟浏览器请求头,降低被识别概率 page.set_extra_http_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"}) # 访问目标页面,等待网络空闲确保加载完成 page.goto("https://www.epicgames.com/store/zh-CN/free-games", wait_until="networkidle") # 获取渲染后的完整HTML html = page.content() browser.close() # 用BeautifulSoup解析处理 soup = BeautifulSoup(html, "html.parser") # 后续提取游戏信息的逻辑...headless设为False,手动完成一次验证后,工具会保存会话信息,后续请求大概率能自动通过。
2. 复用浏览器已通过验证的Cookie
- 先在浏览器中打开Epic免费游戏页面,完成Cloudflare验证;
- 打开F12开发者工具,在「网络」标签页找到目标页面的请求,复制请求头里的
Cookie和User-Agent; - 在
requests中添加这些请求头:
注意:这种方法有效期很短,Cloudflare的Cookie会定期失效,需要重新获取,仅适合临时测试,不适合长期自动运行的需求。import requests from bs4 import BeautifulSoup headers = { "User-Agent": "你的浏览器实际User-Agent", "Cookie": "从浏览器复制的完整Cookie字符串" } response = requests.get("https://www.epicgames.com/store/zh-CN/free-games", headers=headers) soup = BeautifulSoup(response.text, "html.parser") # 后续处理逻辑...
3. 调用Epic官方API(最优解)
Epic提供了公开的商店API,可直接获取免费游戏数据,无需处理页面渲染和反爬:
- 示例代码:
这种方法稳定可靠,完全不会触发Cloudflare验证,最适合长期每周自动获取资讯的需求。import requests # 免费游戏API接口,支持指定地区和语言 url = "https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions?locale=zh-CN&country=CN&allowCountries=CN" response = requests.get(url) data = response.json() # 提取有效免费游戏信息 free_games = data["data"]["Catalog"]["searchStore"]["elements"] for game in free_games: if game.get("promotions") and game["promotions"].get("promotionalOffers"): print(f"游戏名称:{game['title']}") print(f"原价:{game['price']['totalPrice']['originalPrice']}元") print(f"免费截止时间:{game['promotions']['promotionalOffers'][0]['promotionalOffers'][0]['endDate']}") print("---")
内容的提问来源于stack exchange,提问作者M. arco
相关产品推荐
相关产品推荐

