selenium python 截图_如何在python中使用Selenium WebDriver截取部分屏幕截图?

我为此进行了很多搜索,但找不到解决方案。 这是java中可能的解决方案的类似问题。

Python中有类似的解决方案吗?

除了硒以外,此示例还需要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徽标!!!

当然,现在仅获取静态图像将是过大的选择,但是如果您想要获取需要Javascript才能实现的功能,那可能是一个可行的解决方案。

您也可以直接在内存中获取屏幕截图:img = Image.open(StringIO(base64.decodestring(driver.get_screenshot_as_base64())))

我确认使用Firefox驱动程序,该解决方案(以及@ ejk314s的建议)与Selenium 2.38.4一起使用时效果很好

很好的答案,非常感谢!

内存加载的替代方法是img = fox.get_screenshot_as_png(),然后img = Image.open(StringIO(img))将其加载为PIL映像。

注释来自@ sukrit-gupta的NAA:RandomPhobia,对于不需要滚动的静态页面,您的答案非常有用。万一某人需要从需要滚动的大页面获取图像,则应使用location_once_scrolled_into_view函数。因此,将location = element.location替换为:location = img.location_once_scrolled_into_view另外,请确保使用Chrome而不是Firefox,因为Chrome仅截取可见区域的屏幕快照,而Firefox截取完整标签的屏幕快照。

我们如何捕获浏览器中显示的内容而不滚动页面而不是整个页面。

由于某些原因,im.save(screenshot.png)无法保存。

@User"某种原因还不够"每当您不知道期望什么时,U应该用try / except换行并从Exception打印str(e)。也许您没有正确加载或处理图像,所以保存将不起作用,但是无论如何,使用try块将得到错误并能够解决它。

@yellowcap提出的建议的后续工作:请注意,在Python 3+中,您应该BytesIO而不是StringIO。

图像被放大时,我面临尺寸调整问题。屏幕截图有效,但是裁剪图像似乎无效。有人面对过同样的事情吗?

在MacOS(视网膜)上,由于调整大小/比例,存在像素中的Web元素位置与屏幕快照中的元素位置不匹配的问题

如@Outside_Box所述,有时由于屏幕的像素密度,应进行一些更正。因为element.size以磅为单位,并且crop函数使用像素,所以我们应该使用像素比率来转换大小。 pixel_ratio = fox.execute_script("return window.devicePixelRatio") new_size = old_size * pixel_ratio

屏幕截图的大小和浏览器窗口的大小相同。我必须执行以下操作1.使用driver.get_window_size()获取浏览器窗口的大小2.从浏览器窗口的高度减去地址栏的高度3.现在将屏幕截图的大小调整为设置1和2的新高度和宽度

@vperezb实际上因为old_size是dict而pixel_ratio是int,所以需要重新计算高度和宽度:right = location[x] + old_size[width]* pixel_ratio bottom = location[y] + old_size[height]* pixel_ratio

就像@User提到的那样,im.save不能保存,但是也不会引发错误,对此我应该问一个新的问题吗?当我键入im.show()时,将出现一个所需大小的透明图像窗口

在python3.5中为我工作

from selenium import webdriver

fox = webdriver.Firefox()

fox.get('http://stackoverflow.com/')

image = fox.find_element_by_id('hlogo').screenshot_as_png

@Julius不,不应该-仅当部分屏幕截图与分配了ID的元素完全匹配时才足够。

@Julius仍然不确定它在哪里以及如何工作。在带有Chrome的Python 2.7中,它不起作用。

我使用selenium2在chrome / python 2.7上工作。 image = driver.find_element_by_id(el_id).screenshot_as_png这是元素的属性,如何将其保存为图像?

我们如何继续保存图像?

我写了这个有用的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图像。

限制:元素必须适合视口。

您必须安装棒模块才能使用它。

好的代码!当我尝试使用chrome中的长页面时,我认为x = element.location_once_scrolled_into_view["x"] y = element.location_once_scrolled_into_view["y"]是因为location可能返回比窗口大的y。

这是一个执行此功能的函数,在将大小传递给crop函数之前,必须将其大小转换为整数:

from PIL import Image

from StringIO import StringIO

def capture_element(element,driver):

location = element.location

size = element.size

img = driver.get_screenshot_as_png()

img = Image.open(StringIO(img))

left = location['x']

top = location['y']

right = location['x'] + size['width']

bottom = location['y'] + size['height']

img = img.crop((int(left), int(top), int(right), int(bottom)))

img.save('screenshot.png')

这与接受的答案几乎相同,但又增加了一个错误,即OP不希望使用硒。

它确实使用硒,但是这里不需要import语句,它还包括将位置从float转换为int的功能,如果位置不是整数,则img.crop函数将引发异常

TypeError: initial_value must be str or None, not bytes

您的输出是什么(img),是方法还是字节对象?

我不确定我是否理解你的问题

为响应RandomPhobia的一个很好的回答,扩展注释,以下是两个具有正确导入语句的解决方案,它们可以打开全屏屏幕截图,而无需先保存到文件中:

from selenium import webdriver

from PIL import Image

from StringIO import StringIO

import base64

DRIVER = 'chromedriver'

browser = webdriver.Chrome(DRIVER)

browser.get("http:\\\\www.bbc.co.uk" )

img 1 = Image.open(StringIO(base64.decodestring(browser.get_screenshot_as_base64())))

img 2 = Image.open(StringIO(browser.get_screenshot_as_png()))

并且因为我确定您的下一个问题是:"很好,但是哪个最快?",这是确定方法的方法(我发现第一种方法在一定距离内最快):

import timeit

setup = '''

from selenium import webdriver

from PIL import Image

from StringIO import StringIO

import base64

DRIVER = 'chromedriver'

browser = webdriver.Chrome(DRIVER)

browser.get("http:\\\\www.bbc.co.uk" )

file_name = 'tmp.png'

'''

print timeit.Timer('Image.open(StringIO(browser.get_screenshot_as_png()))', setup=setup).repeat(2, 10)

print timeit.Timer('Image.open(StringIO(base64.decodestring(browser.get_screenshot_as_base64())))', setup=setup).repeat(2, 10)

print timeit.Timer('browser.get_screenshot_as_file(file_name); pil_img = Image.open(file_name)', setup=setup).repeat(2, 10)

这个名叫" Cherri"的家伙为Selenium创建了一个包含此库的库。

import SeleniumUrllib as selenium

selenium_urllib = selenium()

selenium_urllib.element_screenshot(selectbyid('elementid'),'path.png')

selenium_urllib.driver ## Access normal webdriver

无效链接,请对其进行更新。

@PedroLobito实际上是一个被黑的链接。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值