Python中headless浏览器如何抓取网页中的ajax请求并用js模拟发送?

RT,最近玩 scrapy 有这方面的需求,不知道有没有办法以 middlewares 的手段去抓取 JS 标签里的 ajax 请求,并模拟发送。 是否只能手动提取,再组合参数发送?

在线等大佬解答,感谢!!


Python中headless浏览器如何抓取网页中的ajax请求并用js模拟发送?
7 回复

https://medium.com/@gilfink/quick-tip-creating-an-xmlhttprequest-interceptor-1da23cf90b76


import asyncio
from pyppeteer import launch

async def capture_ajax_requests():
    # 启动headless浏览器
    browser = await launch(headless=True)
    page = await browser.newPage()
    
    # 监听网络请求
    requests = []
    def on_request(request):
        if request.resourceType == 'xhr' or request.resourceType == 'fetch':
            requests.append({
                'url': request.url,
                'method': request.method,
                'headers': request.headers,
                'postData': request.postData
            })
    page.on('request', on_request)
    
    # 访问目标页面
    await page.goto('https://example.com')
    await page.waitFor(3000)  # 等待页面加载和AJAX请求
    
    # 提取并模拟发送请求
    for req in requests:
        # 使用fetch API模拟发送
        await page.evaluate('''(reqData) => {
            return fetch(reqData.url, {
                method: reqData.method,
                headers: reqData.headers,
                body: reqData.postData
            }).then(r => r.text());
        }''', req)
    
    await browser.close()
    return requests

# 运行
requests = asyncio.get_event_loop().run_until_complete(capture_ajax_requests())
print(f"捕获到 {len(requests)} 个AJAX请求")

核心步骤:

  1. 用Pyppeteer启动headless浏览器并监听XHR/Fetch请求
  2. 访问页面让JavaScript执行,捕获所有AJAX请求详情
  3. 通过page.evaluate()在页面上下文中用fetch API重新发送请求
  4. 可以修改请求参数或添加自定义逻辑

关键点:

  • 监听request事件时过滤resourceTypexhrfetch
  • 保存请求的URL、方法、头部和POST数据
  • 在页面上下文中用JavaScript的fetch API重新发送
  • 可以结合page.waitForSelector()等待特定元素出现后再捕获请求

建议:优先使用浏览器原生API模拟,避免直接解析复杂JS。

目前只想到可以搞个 polyfill,然后拦截

hookajax 以及 fetch 的 polyfill 就能在 js 层面把请求拦下来了
不过浏览器都能控制的话 为啥不直接看浏览器开发人员工具提供的 network 呢

您的意思是拦截器监控再复现?但是我在随机爬行某个网站时不一定能触发该 js 函数,我这算是黑盒,白盒的应该不太适用。



感谢两位的回复,两位说的都是拦截器吧,不过我黑盒爬虫去爬不一定能触发 ajax,靠这个拦截复现不太现实。。

回到顶部