如何用Python的Selenium WebDriver截取部分屏幕截图?

92 投票
8 回答
91486 浏览
提问于 2025-04-17 16:43

我搜索了很多,但还是找不到解决办法。这里有一个类似的问题,里面有一个可能的Java解决方案。

那在Python中有没有类似的解决办法呢?

8 个回答

9

我写了一个很实用的Python3函数。

from base64 import b64decode
from wand.image import Image
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.action_chains import ActionChains
import math

def get_element_screenshot(element: WebElement) -> bytes:
    driver = element._parent
    ActionChains(driver).move_to_element(element).perform()  # focus
    src_base64 = driver.get_screenshot_as_base64()
    scr_png = b64decode(src_base64)
    scr_img = Image(blob=scr_png)

    x = element.location["x"]
    y = element.location["y"]
    w = element.size["width"]
    h = element.size["height"]
    scr_img.crop(
        left=math.floor(x),
        top=math.floor(y),
        width=math.ceil(w),
        height=math.ceil(h),
    )
    return scr_img.make_blob()

这个函数会把显示的元素转换成PNG格式的图片,并以字节的形式返回。
不过有个限制:这个元素必须能在视口(也就是你能看到的区域)内显示出来。
你需要安装wand这个模块才能使用它。

52

在Python 3.5中对我有效

from selenium import webdriver


fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')
image = fox.find_element_by_id('hlogo').screenshot_as_png

附注:

要保存到文件中

image=driver.find_element_by_id('hlogo').screenshot(output_file_path)
164

除了Selenium,这个例子还需要用到PIL图像处理库。有时候这个库会被当作标准库之一,有时候又不是。如果你没有这个库,可以通过运行 pip install Pillow 来安装它。

from selenium import webdriver
from PIL import Image
from io import BytesIO

fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')

# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
png = fox.get_screenshot_as_png() # saves screenshot of entire page
fox.quit()

im = Image.open(BytesIO(png)) # uses PIL library to open image in memory

left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']


im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image

最后的输出就是……Stackoverflow的logo!!!

在这里输入图片描述

当然,单单为了获取一张静态图片,这种方法有点过于复杂了。不过如果你想抓取一些需要用到Javascript才能获取的内容,这种方法就很有用了。

撰写回答