如何通过chrome远程调试获取网页资源内容

Posted

技术标签:

【中文标题】如何通过chrome远程调试获取网页资源内容【英文标题】:how to get webpage resource content via chrome remote debugging 【发布时间】:2016-08-01 07:41:30 【问题描述】:

我想通过Chrome调试协议使用python获取网页资源内容,从这个页面method-getResourceContent,我注意到这个方法:getResourceContent,需要参数frameId和url。我认为这个方法是我需要的。 所以我做了这件事:

1.get start chrome 作为服务器:.\chrome.exe --remote-debugging-port=9222

2.编写python测试代码:

# coding=utf-8
"""
chrome --remote-debugging api test
"""

import json
import requests
import websocket

import pdb

def send():
    geturl = requests.get('http://localhost:9222/json')
    websocketURL = json.loads(geturl.content)[0]['webSocketDebuggerUrl']
    request = 
    request['id'] = 1
    request['method'] = 'Page.navigate'
    request['params'] = "url": 'http://global.bing.com'
    ws = websocket.create_connection(websocketURL)
    ws.send(json.dumps(request))
    res = ws.recv()
    ws.close()
    print res

    frameId = json.loads(res)['result']['frameId']
    print frameId
    geturl = requests.get('http://localhost:9222/json')
    websocketURL = json.loads(geturl.content)[0]['webSocketDebuggerUrl']
    req = 
    req['id'] = 1
    req['method'] = 'Page.getResourceContent'
    req['params'] = "frameId":frameId,"url": 'http://global.bing.com'
    header = ["User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/51.0.2704.103 Safari/537.36"]
    pdb.set_trace()
    ws = websocket.create_connection(websocketURL,header=header)
    ws.send(json.dumps(req))
    ress = ws.recv()
    ws.close()
    print ress
if __name__ == '__main__':
    send()

3.Page.navigate 工作正常,我得到了这样的东西: "id":1,"result":"frameId":"8504.2"

4.当我尝试方法时:getResourceContent,错误出来了: "error":"code":-32000,"message":"代理未启用。","id":1

我尝试添加User-Agent,还是不行。

谢谢。

【问题讨论】:

【参考方案1】:

错误消息“代理未启用”与 HTTP User-Agent 标头无关,而是指 chrome 中需要启用才能检索页面内容的代理。

术语“代理”有点误导,因为protocol documentation 谈到需要启用才能调试它们的域(术语“代理”指的是在 Chrome 内部实现的方式,我想)

那么,问题是需要启用哪个域才能访问页面内容?事后看来,这很明显:Page 域需要启用,因为我们正在调用该域中的方法。不过,我是在偶然发现this example 之后才发现的。

一旦我将Page.enable 请求添加到脚本以激活Page 域,错误消息就消失了。但是,我遇到了另外两个问题:

    websockets 连接需要在请求之间保持打开状态,因为 Chrome 会在调用之间保持某些状态(例如是否启用代理) 当导航到 http://global.bing.com/ 时,浏览器被重定向到 http://www.bing.com/(至少它是在我的电脑上)。这会导致 Page.getResourceContent 无法检索资源,因为请求的资源 http://global.bing.com/ 不可用。

修复这些问题后,我能够检索页面内容。这是我的代码:

# coding=utf-8
"""
chrome --remote-debugging api test
"""

import json
import requests
import websocket

def send():
    # Setup websocket connection:
    geturl = requests.get('http://localhost:9222/json')
    websocketURL = json.loads(geturl.content)[0]['webSocketDebuggerUrl']
    ws = websocket.create_connection(websocketURL)

    # Navigate to global.bing.com:
    request = 
    request['id'] = 1
    request['method'] = 'Page.navigate'
    request['params'] = "url": 'http://global.bing.com'
    ws.send(json.dumps(request))
    result = ws.recv()
    print "Page.navigate: ", result
    frameId = json.loads(result)['result']['frameId']

    # Enable page agent:
    request = 
    request['id'] = 1
    request['method'] = 'Page.enable'
    request['params'] = 
    ws.send(json.dumps(request))
    print 'Page.enable: ', ws.recv()

    # Retrieve resource contents:
    request = 
    request['id'] = 1
    request['method'] = 'Page.getResourceContent'
    request['params'] = "frameId": frameId, "url": 'http://www.bing.com'
    ws.send(json.dumps(request))
    result = ws.recv()
    print("Page.getResourceContent: ", result)

    # Close websocket connection
    ws.close()

if __name__ == '__main__':
    send()

【讨论】:

当你使用像PyChrome这样的Python Devtools API客户端时,这会容易得多

以上是关于如何通过chrome远程调试获取网页资源内容的主要内容,如果未能解决你的问题,请参考以下文章

Chrome远程调试手机端UC浏览器

用Chrome浏览器远程调试APP内的网页,其实是支持哒

Chrome 远程调试 - 获取页面通知

利用 Chrome 开发者工具远程调试 Android 中的原生 WebView

有没有办法通过远程调试协议或通过命令行启动它从 Edge 浏览器获取任何控制台消息?

如何通过Chrome远程调试android设备上的Web网站