如何使用chromedp(或替代方案)拦截网络流量并获得响应?

时间:2017-11-01 10:26:28

标签: google-chrome go network-programming google-chrome-devtools

我的目标是从目标服务器获取一个无法直接检索的特定响应,但是通过使用Web驱动程序来启动网页中固有的javascript代码启动的请求一旦加载。该请求包含一些用于服务器端验证的代码,目前我无法解码生成算法。

Chrome中的“开发人员工具”提供了一种检查请求和响应的便捷方式,我需要使用强大的库(例如chromedp)自动完成此过程。

AFAIK network包提供了GetResponseBody功能,但需要requestID参数。如何获取特定的请求ID?

cdp.ActionFunc(func(ctxt context.Context, h cdptypes.Handler) error {
        rptn := &network.RequestPattern{
            ResourceType: page.ResourceTypeScript,
        }
        network.SetRequestInterception([]*network.RequestPattern{rptn}).Do(ctxt, h)

        //begin interception
        network.ContinueInterceptedRequest("AlphaInterceptor").Do(ctxt, h)

        //How to identify the requestID?
        network.GetResponseBody("???")

        ...
}

1 个答案:

答案 0 :(得分:0)

当时chromedp lib似乎还不完整。我已经实现了事件监听机制并提交了pull request。对于那些需要的人,可以通过监听网络事件获取特定的服务器资源,并分别获取RequestID和响应主体:

cdp.Tasks{
    cdp.ActionFunc(func(ctxt context.Context, h cdptypes.Handler) error {
        go func() {
            echan := h.Listen(cdptypes.EventNetworkRequestWillBeSent, cdptypes.EventNetworkLoadingFinished)
            for d := range echan {
                switch d.(type) {
                case *network.EventRequestWillBeSent:
                    req := d.(*network.EventRequestWillBeSent)
                    if strings.HasSuffix(req.Request.URL, "/data_I_want.js") {
                        reqId1 = req.RequestID
                    } else if strings.HasSuffix(req.Request.URL, "/another_one.js") {
                        reqId2 = req.RequestID
                    }
                case *network.EventLoadingFinished:
                    res := d.(*network.EventLoadingFinished)
                    var data []byte
                    var e error
                    if reqId1 == res.RequestID {
                        data, e = network.GetResponseBody(reqId1).Do(ctxt, h)
                    } else if reqId2 == res.RequestID {
                        data, e = network.GetResponseBody(reqId2).Do(ctxt, h)
                    }
                    if e != nil {
                        panic(e)
                    }
                    if len(data) > 0 {
                        fmt.Printf("=========data: %+v\n", string(data))
                    }
                }
            }
        }()
        return nil
    }),
    cdp.Navigate(url),
    ...
}