簡體   English   中英

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

[英]How to take partial screenshot with Selenium WebDriver in python?

我為此搜索了很多,但找不到解決方案。 這是一個類似的問題,在 Java 中有一個可能的解決方案。

Python中是否有類似的解決方案?

除了 Selenium,這個例子還需要 PIL Imaging 庫。 有時這是作為標准庫之一放入的,有時不是,但是如果您沒有它,您可以使用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 才能到達的東西,這可能是一個可行的解決方案。

在 python3.5 中為我工作

from selenium import webdriver


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

ps

保存到文件

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

我寫了這個有用的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 圖像。 限制:元素必須適合視口。
您必須安裝魔杖模塊才能使用它。

這是一個執行此操作的函數,在傳遞給裁剪函數之前,必須將大小轉換為整數:

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')

擴展評論以響應 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)

元素截圖:

from PIL import Image
from io import BytesIO


image = self.browser.driver.find_element_by_class_name('example.bla.bla').screenshot_as_png
im = Image.open(BytesIO(image))  # uses PIL library to open image in memory
im.save('example.png')

這個名叫“ Cherri”的家伙為Selenium創建了一個包含此庫的庫

import SeleniumUrllib as selenium
selenium_urllib = selenium()
selenium_urllib.element_screenshot(selectbyid('elementid'),'path.png')
selenium_urllib.driver ## Access normal webdriver

就這么簡單:

element = driver.find_element_by_class_name('myclass')
element.screenshot('screenshot.png')

我將@randomphobia 的答案轉換為一個函數。 我還使用了@bummis 的建議,即使用location_once_scrolled_into_view而不是location以便概括無論頁面大小。

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

def take_screenshot(element, driver, filename='screenshot.png'):
  location = element.location_once_scrolled_into_view
  size = element.size
  png = driver.get_screenshot_as_png() # saves screenshot of entire page

  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(filename) # saves new cropped image

這是一個要點: https : //gist.github.com/WittmannF/b714d3ceb7b6a5cd50002f11fb5a4929

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM