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

Pyppeteer无法捕获4xx/5xx响应及JS、AJAX错误的技术问询

问题描述

使用Pyppeteer抓取指定网站的所有控制台消息时,仅能捕获状态码为200的响应,无法获取网站实际存在的4xx、5xx响应,也无法提取JS及AJAX错误。当前代码及运行输出如下:

当前代码

import asyncio
from pyppeteer import launch


async def on_console(msg):
    print('PAGE LOG:', msg.text)

async def on_page_error(error):
    print(error)

async def on_response(response):
    print(f"{response.status} {response.url}")
    

async def on_request_failed(request):
    failure = request.failure()
    if failure:
        print(failure.get('errorText', 'Unknown error'), request.url)
    else:
        print('Request failed without error information', request.url)

async def main():
    
    browser = await launch()
    page = await browser.newPage()

    page.on('console', lambda msg: asyncio.ensure_future(on_console(msg)))
    page.on('pageerror', lambda error: asyncio.ensure_future(on_page_error(error)))
    page.on('response', lambda response: asyncio.ensure_future(on_response(response)))
    page.on('requestfailed', lambda request: asyncio.ensure_future(on_request_failed(request)))

    try:
        await page.goto('https://toursthingstodo.com')
        await page.waitFor(5000)
    except Exception as e:
        print(f"An error occurred: {e}")

    await browser.close()


asyncio.run(main())

当前运行输出

200 https://toursthingstodo.com/
200 https://toursthingstodo.com/_next/static/css/cfeb154ff119552e.css
200 https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3751418851639209

网站实际存在的错误(翻译自截图)

  • 资源加载错误:GET https://toursthingstodo.com/_next/static/media/logo.8e5b40b0.png 404 (未找到)
  • JS运行错误:未捕获的引用错误:$ is not defined
  • AJAX请求错误:POST https://toursthingstodo.com/api/data 500 (内部服务器错误)

解决方案

一、使用Pyppeteer实现完整错误捕获

现有代码遗漏了部分事件监听,且对response事件的处理不够全面,调整后可以捕获所有目标错误:

改进后的代码

import asyncio
from pyppeteer import launch

async def on_console(msg):
    # 区分控制台消息类型:错误、警告、日志等
    msg_type = msg.type
    if msg_type == 'error':
        print(f'[控制台错误] {msg.text}')
    elif msg_type == 'warning':
        print(f'[控制台警告] {msg.text}')
    else:
        print(f'[控制台日志] {msg.text}')

async def on_page_error(error):
    print(f'[页面全局错误] {error}')

async def on_response(response):
    # 捕获所有响应,包括4xx、5xx状态码
    status = response.status
    if 400 <= status < 600:
        print(f'[异常响应] {status} {response.url}')
    else:
        print(f'[正常响应] {status} {response.url}')

async def on_request_failed(request):
    failure = request.failure()
    if failure:
        print(f'[请求失败] {failure.get("errorText", "未知错误")} {request.url}')
    else:
        print(f'[请求失败] 无错误信息 {request.url}')

async def main():
    # 启动浏览器时开启日志,方便排查网络问题
    browser = await launch(headless=False, args=['--disable-web-security', '--enable-logging'])
    page = await browser.newPage()
    
    # 监听所有关键事件
    page.on('console', lambda msg: asyncio.ensure_future(on_console(msg)))
    page.on('pageerror', lambda error: asyncio.ensure_future(on_page_error(error)))
    page.on('response', lambda response: asyncio.ensure_future(on_response(response)))
    page.on('requestfailed', lambda request: asyncio.ensure_future(on_request_failed(request)))
    
    # 启用请求拦截,确保捕获所有AJAX请求
    await page.setRequestInterception(True)
    async def intercept_request(request):
        # 放行所有请求
        await request.continue_()
    page.on('request', lambda req: asyncio.ensure_future(intercept_request(req)))
    
    try:
        # 等待页面完全加载,包括所有资源和AJAX请求
        await page.goto('https://toursthingstodo.com', waitUntil='networkidle2', timeout=60000)
        await asyncio.sleep(5)
    except Exception as e:
        print(f'[主流程错误] {e}')
    
    await browser.close()

asyncio.run(main())

关键改进点

  • 完善response事件处理:主动判断状态码是否为4xx/5xx,这类响应不会触发requestfailed事件,需要单独处理
  • 启用请求拦截:确保捕获所有AJAX请求,包括动态发起的异步请求
  • 细化控制台消息类型:区分错误、警告和普通日志,精准定位问题
  • 调整页面加载策略:使用waitUntil='networkidle2'等待网络空闲,确保所有资源加载完成

二、其他可选Python库

如果Pyppeteer使用起来有门槛,还可以考虑以下工具:

  • Playwright:Pyppeteer的替代方案,API更简洁,支持多浏览器(Chrome、Firefox、Safari),内置更完善的错误捕获机制
  • Selenium:老牌自动化测试工具,结合浏览器驱动可以捕获控制台错误和网络请求,适合复杂场景
  • requests + BeautifulSoup + aiohttp:如果不需要渲染JS,仅需捕获AJAX错误,可以直接用HTTP请求库模拟,但无法处理前端JS运行错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:36:01