如何通过无头Chrome结合Chrome DevTools Protocol获取页面链接?
获取页面链接:CDP Runtime API的正确用法
当然可以通过无头Chrome结合Chrome DevTools Protocol(CDP)获取页面链接!你遇到的问题主要是因为Runtime.runScript()默认不会返回脚本执行的结果——它的设计初衷更多是执行无需返回值的脚本逻辑,而非获取执行输出。
问题根源
你的代码里调用了Runtime.compileScript()和Runtime.runScript(),但没有配置返回结果的参数。而且document.links是一个HTMLCollection(类数组的DOM集合),直接返回的话序列化会有问题,需要先转换成可序列化的格式(比如字符串数组)。
解决方案1:修改runScript参数获取返回值
调整Runtime.runScript()的调用,添加returnByValue: true参数开启返回值,同时把document.links转换成可序列化的链接数组:
const script = { expression: "Array.from(document.links).map(link => link.href)", sourceURL: "https://www.github.com", persistScript: true }; const actionResponse = await Runtime.compileScript(script); const result = await Runtime.runScript({ scriptId: actionResponse.scriptId, returnByValue: true // 关键:启用返回值 }); console.log(result.result.value); // 输出页面所有链接的href数组
解决方案2:用Runtime.evaluate()更简洁(推荐)
如果只是单次执行脚本获取结果,Runtime.evaluate()比compileScript+runScript更直接,它专门用于执行脚本并返回结果:
const evaluateResponse = await Runtime.evaluate({ expression: "Array.from(document.links).map(link => link.href)", returnByValue: true }); console.log(evaluateResponse.result.value); // 直接拿到链接数组
额外说明
Array.from(document.links)把HTMLCollection转换成普通数组,再通过map提取每个链接的href属性,确保返回的是可被CDP序列化的字符串数组。- 如果需要处理更复杂的DOM元素,也可以使用CDP的
DOM系列API(比如DOM.querySelectorAll)来定位元素,再提取属性,但Runtime.evaluate()对于直接执行JS逻辑来说更灵活便捷。
内容的提问来源于stack exchange,提问作者Valip




