当前位置: 首页 > news >正文

使用 Chromedp 监听网页请求和响应

使用 Chromedp 监听网页请求和响应

在进行网络爬虫的时候,有很多网站都有反爬机制,比如你想抓点数据,结果发现每次请求都带一堆奇奇怪怪的参数 —— 什么 timestamp 签名、AES 加密的字段,还有各种 Token 令牌,跟密码本似的。你直接看网页源代码吧,那些 JS 代码被混淆得亲妈都不认识,像一团乱麻似的根本理不清头绪。

这时候我们可以使用chromedp来监听网页请求,它的核心价值在于:第一不用费劲巴拉地去解密那些被混淆的 JS 代码,直接拿现成的参数用;第二能盯着不同操作时参数怎么变,比如刷新页面时哪个值会变,登录时多了哪个字段;

什么是 Chromedp

ChromeDP 是一个 Go 语言实现的库,它提供了无头浏览器的操作和控制能力,可以用来进行网页自动化、爬虫和测试等工作。通过 ChromeDP,我们可以编程方式监听网页上的各种事件,包括网络请求和响应。

环境准备

首先,我们需要安装 Go 和 ChromeDP 库:

// 安装 ChromeDP
go get -u github.com/chromedp/chromedp

演示代码

下面是一个基本的示例,演示如何使用 ChromeDP 监听网页请求:

package main

import (
	"context"
	"encoding/base64"
	"fmt"
	"log"
	"time"

	"github.com/chromedp/cdproto/network"
	"github.com/chromedp/chromedp"
)

func EnBase64(base64String string) string {
	decodedBytes, err := base64.StdEncoding.DecodeString(base64String)
	if err != nil {
		log.Println("解码错误:", err)
		return ""
	}
	return string(decodedBytes)
}

func main() {
	// 创建一个带取消功能的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
	defer cancel()

	// 创建一个ChromeDP选项,启用网络事件
	opts := append(chromedp.DefaultExecAllocatorOptions[:],
		chromedp.Flag("headless", false),
		chromedp.Flag("disable-gpu", true),
		chromedp.Flag("enable-automation", true),
		chromedp.Flag("disable-extensions", true),
	)

	allocCtx, cancel := chromedp.NewExecAllocator(ctx, opts...)
	defer cancel()

	// 创建一个新的浏览器实例
	taskCtx, taskCancel := chromedp.NewContext(allocCtx)
	defer taskCancel() // 确保在退出时取消 taskCtx

	// 监听请求开始事件
	chromedp.ListenTarget(taskCtx, func(ev interface{}) {
		switch e := ev.(type) {
		case *network.EventRequestWillBeSent:
			// 打印请求信息
			fmt.Printf("请求URL: %s\n", e.Request.URL)
			fmt.Printf("请求方法: %s\n", e.Request.Method)
			fmt.Printf("请求头: %v\n", e.Request.Headers)
			// 如果有请求体,打印请求体
			if e.Request.HasPostData {
				entries := e.Request.PostDataEntries
				for _, entry := range entries {
					fmt.Printf("请求体: %s\n", EnBase64(entry.Bytes))
				}
			}
			fmt.Println("------------------------")

		case *network.EventResponseReceived:
			// 打印响应信息
			fmt.Printf("响应URL: %s\n", e.Response.URL)
			fmt.Printf("响应状态: %d\n", e.Response.Status)
			fmt.Printf("响应头: %v\n", e.Response.Headers)

			// 获取响应体
			/*
			不知道怎么回事直接在ListenTarget中使用GetResponseBody,会一直报错invalid context
			关于GetResponseBody 处理可以看 https://github.com/chromedp/chromedp/issues/427
			*/
			go func() {
				
				chromedp.Run(taskCtx, chromedp.ActionFunc(func(ctx context.Context) error {
					body, err := network.GetResponseBody(e.RequestID).Do(ctx)
					if err != nil {
						fmt.Println(err)
					}
					fmt.Printf("响应体: %s\n", string(body))
					return nil
				}))
			}()

			fmt.Println("------------------------")
		}
	})

	// 启用网络监听
	if err := chromedp.Run(taskCtx,
		network.Enable(),
		// 访问指定网页
		chromedp.Navigate("https://blog.csdn.net/yang731227"),
		// 等待页面加载完成
		chromedp.Sleep(15*time.Second),
	); err != nil {
		log.Fatal(err)
	}
}


过滤特定类型的请求

如果您只想监听特定类型的请求(例如,只关注 XHR 请求或特定 URL 模式),可以这样做:

// 在 EventRequestWillBeSent 事件处理中添加过滤逻辑
case *network.EventRequestWillBeSent:
    // 只关注 XHR 请求
    if e.Type == network.ResourceTypeXHR {
        fmt.Printf("XHR请求: %s %s\n", e.Request.Method, e.Request.URL)
    }
    
    // 或者只关注特定URL模式
    if strings.Contains(e.Request.URL, "api") {
        fmt.Printf("API请求: %s %s\n", e.Request.Method, e.Request.URL)
    }

相关文章:

  • 利用脚本和Shader制作屏幕后处理效果
  • MOSN(Modular Open Smart Network)-04-TLS 安全链路
  • HCIA复习
  • go-zero: sqlx 对timestamp 格式数据问题
  • 罗杰斯特回归
  • 四川省汽车加气站操作工备考题库及答案分享
  • 蓝桥杯练习题--一年中的第几天
  • Numpy基础
  • LLM 加速技术有哪些
  • Linux--文件
  • “Failed to load steamui.dll” 文件丢失:原因分析与全面修复指南
  • UE5小石子阴影在非常近距离才显示的问题
  • 告别Win10强制更新:永久关闭系统更新指南
  • Node.js 下载安装及环境配置教程、卸载删除环境配置超详细步骤(附图文讲解!) 从零基础入门到精通,看完这一篇就够了
  • Day16 -实例:Web利用邮箱被动绕过CDN拿真实ip
  • 鸿蒙生态全解析:应用适配分享
  • 【Python · PyTorch】时域卷积网络 TCN
  • 【字符设备驱动开发–IMX6ULL】(一)简介
  • NLP高频面试题(十八)——什么是prefill和decoder分离架构
  • CAS(Compare And Swap)
  • 俄媒:俄乌代表团抵达谈判会场
  • 手机表面细菌菌落总数可能比马桶高10倍,医生详解如何洗手
  • 鸿海下调全年营收展望:AI服务器业务强劲,预计今年营收增超50%
  • 马上评|安排见义勇为学生补考,善意与善意的双向奔赴
  • 日本广岛大学一处拆迁工地发现疑似未爆弹
  • 真人秀《幸存者》百万美元奖金,25年间“缩水”近一半