Selenium做自动化时截取浏览器全屏页面
做web自动化时,大多是用selenium,用过的都知道selenium是有个接口可以保存网页截图,不过是当前可视范围的,无法截取全屏。
而我当前在做一个基于视觉处理的测试框架,为的是简化代码和模拟真人的操作方式,于是便需要能截取全屏。因为对于有些场景下需要找到所有的按钮之类的元素,有些场景下需要能确定控件的位置并滑动过去,否则只是当前默认的位置并没有显示出,便无法预测控件类型。
实际浏览器是能支持截取全屏的功能。只是selenium并没有提供能实施这些命令的接口,于是导致不可用。
比如对于chrome,用F12打开dev tool,输入command+shift+p(非mac的把command换成ctrl),然后输入full,便能看到一个命令”capture full size screenshot“,运行它便能获得当前页面的全屏截图。既然有这个命令,那么我也可以调这个命令。
对应的指令是:
/session/:sessionId/chromium/send_command_and_get_result
比如python代码如下:
from selenium import webdriver
import json, base64
def capture_full_screen(driver) :
def send(cmd, params):
resource = "/session/%s/chromium/send_command_and_get_result" % driver.session_id
url = driver.command_executor._url + resource
body = json.dumps({"cmd":cmd, "params": params})
response = driver.command_executor._request("POST", url, body)
return response.get("value")
def evaluate(script):
response = send("Runtime.evaluate", {"returnByValue": True, "expression": script})
return response["result"]["value"]
metrics = evaluate(\
"({" + \
"width: Math.max(window.innerWidth, document.body.scrollWidth, document.documentElement.scrollWidth)|0," + \
"height: Math.max(innerHeight, document.body.scrollHeight, document.documentElement.scrollHeight)|0," + \
"deviceScaleFactor: window.devicePixelRatio || 1," + \
"mobile: typeof window.orientation !== 'undefined'" + \
"})")
send("Emulation.setDeviceMetricsOverride", metrics)
screenshot = send("Page.captureScreenshot", {"format": "png", "fromSurface": True})
send("Emulation.clearDeviceMetricsOverride", {})
return base64.b64decode(screenshot["data"])
if __name__ == "__main__":
driver = webdriver.Chrome()
driver.get("https://pytorch.org/tutorials/beginner/saving_loading_models.html#")
screenshot = capture_full_screen(driver)
with open("./full.png", 'wb') as f:
f.write(screenshot)
driver.quit()
对于firefox也是类似。可以按command+option+k(非mac用ctrl+shift+k)调出dev tool console,然后输入:screenshot --fullpage,便能看到全屏页面被保存下来了。
但是上面的方法得改,因为对于firefox的command url是
/session/:sessionid/moz/screenshot/full
并且是用GET。代码会调整为如下:
def capture_full_screen(driver):
resource = "/session/%s/moz/screenshot/full" % driver.session_id
url = driver.command_executor._url + resource
print(url)
content = driver.command_executor._request("GET", url)
with open("./firefox.png", "wb") as f:
f.write(base64.b64decode(content["value"]))
参考链接:
https://w3c.github.io/webdriver/webdriver-spec.html#dfn-take-screenshot
https://stackoverflow.com/questions/45199076/take-full-page-screenshot-in-chrome-with-selenium