为何调用urllib.request下的urlopen方法无法正常获取目标网页内容
问题原因分析
- 你用的URL带
#属于前端哈希路由,#后的内容不会发送到服务端,直接请求该地址返回的是站点入口静态HTML,你需要的统计数据是页面加载后由JS动态渲染生成的,urllib仅能获取静态页面内容,无法拿到动态渲染后的数据。 urllib默认发送的请求头User-Agent为Python-urllib/[版本号],绝大多数站点会直接拦截这类爬虫特征明显的请求,没有加超时参数的情况下就会出现长时间无响应的问题。
解决办法
方案1:抓动态接口请求(效率最高)
打开浏览器F12开发者工具,切换到「网络」面板,刷新页面后筛选XHR/ Fetch请求,找到返回统计数据的真实接口,直接请求该接口即可,请求时需要带上符合浏览器特征的请求头,同时添加超时参数避免长时间卡顿:
from urllib.request import Request, urlopen import json 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://www.dreamteamfc.com/' } # 此处替换为你抓到的真实数据接口地址 data_api = 'https://www.dreamteamfc.com/[你抓到的接口路径]' req = Request(data_api, headers=headers) # 加10秒超时,请求失败直接抛出错误不会一直卡 resp = urlopen(req, timeout=10) data = json.loads(resp.read().decode('utf-8'))
方案2:模拟浏览器获取渲染后页面
如果接口参数有加密难以解析,可以用Selenium、Playwright这类模拟浏览器工具,等页面渲染完成后再提取数据,示例用Playwright:
from playwright.sync_api import sync_playwright import bs4 as bs with sync_playwright() as p: # 可设置headless=True后台运行浏览器 browser = p.chromium.launch(headless=False) page = browser.new_page(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.dreamteamfc.com/g/#tournament/stats-centre-stats', timeout=30000) # 等待目标统计元素加载完成,选择器替换为实际页面的对应元素选择器 page.wait_for_selector('.stats-centre-table', timeout=10000) # 获取渲染完成的完整页面代码 page_html = page.content() soup = bs.BeautifulSoup(page_html, 'html.parser') # 后续解析soup提取所需数据即可 browser.close()
注意事项
- 所有请求都要添加超时参数,避免无意义的长时间等待
- 控制请求频率,可添加随机间隔,避免被站点封禁IP
- 优先使用抓接口的方案,比模拟浏览器的性能高几十倍,开发成本也更低
内容的提问来源于stack exchange,提问作者ad282189323213
相关产品推荐
相关产品推荐

