【分享】selenium部分元素截图的另类解决方案

如何截图某个元素的图?不要全部的,只要某个元素。
网上流传的部分方案:
方案1:

from  selenium import  webdriver

driver=webdriver.Chrome()
driver.get('http://www.baidu.com')
ele=driver.find_element_by_css_selector('#su')
ele.screenshot('xxx.png')

某些场景会有Bug。
方案2:
截取全图,然后获取元素位置、大小;最后进行相应的裁剪和拼接。

from selenium import webdriver
from PIL import Image

driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')
driver.save_screenshot('baidu.png')
element = driver.find_element_by_id("su")
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']
im = Image.open('baidu.png')
im = im.crop((left, top, right, bottom))
im.save('su_button.png')

优点: 实现简单
缺点: 对于高度太高的页面会导致文件过大,处理会有问题

那有没有别的方案呢,经过研究selenium screenshot_as_base64的源码,我找到了

Command.ELEMENT_SCREENSHOT: ('GET', '/session/$sessionId/element/$id/screenshot')

这句,selenium底层调用的是这个接口,所以拿过来使用即可。
sessionid是浏览器的session_idelement/$id 是元素的id

import requests
import base64
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
ele = driver.find_element_by_css_selector('#su')
sessionid = driver.session_id
r = requests.get(f'http://localhost:9102/session/{sessionid}/element/{ele.id}/screenshot')
print(r.status_code)
print(r.text)
with open('su.png', 'wb') as f:
    imgdata = base64.b64decode(r.json()["value"])
    f.write(imgdata)

运行结果为base64,很容易转换为图片。

扩展:
使用原来的Session会话连接,可以无需在启动一个浏览器

方案代码来源:python selenium截图_利用 Python + Selenium 实现对页面的指定元素截图(可截长图元素)..._weixin_39801165的博客-CSDN博客

2 个赞