通过Selenium使用无头ChromeDriver的透明屏幕截图

Col*_*ole 4 selenium python-3.x selenium-chromedriver

据我了解,ChromeDriver本身并没有设置背景,CSS设置了背景。因此,如果背景是透明的,为什么我没有得到透明的屏幕截图?

这是所谓透明网站的屏幕截图: 透明背景 相同的屏幕截图,但背景中有一个红色div以显示透明度应位于的位置: 红色背景

这是我的代码:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from datetime import datetime

options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(chrome_options=options)

driver.set_window_size(2560, 1600)
driver.get('https://twitter.com/realDonaldTrump/status/516382177798680576')
# driver.execute_script("$('body').append(`<div style='background: red; width: 100%; height: 100%;'></div>`);")
driver.save_screenshot('screenshots/' + str(datetime.now()) + '.png')

driver.quit()
Run Code Online (Sandbox Code Playgroud)

我将如何创建该屏幕截图的透明版本?

*编辑* 我总结了如何完成此任务。接受的答案帮助我找到了可以解决的地方,这就是我想要的。但是,这个要点是解决我的问题的正确方法:https : //gist.github.com/colexyz/f58834ff09ab07e3c1164667b753e77a

Flo*_* B. 6

一种方法是通过将alpha字节设置为0,将屏幕截图中的每个白色像素转换为透明像素:

from selenium import webdriver
from PIL import Image
from io import BytesIO # python 3
import numpy as np

def remove_color(img, rgba):
  data = np.array(img.convert('RGBA'))        # rgba array from image
  pixels = data.view(dtype=np.uint32)[...,0]  # pixels as rgba uint32
  data[...,3] = np.where(pixels == np.uint32(rgba), np.uint8(0), np.uint8(255))  # set alpha channel
  return Image.fromarray(data)

driver = webdriver.Chrome()
driver.get("http://www.bbc.co.uk/news")

# take screenshot with a transparent background
with Image.open(BytesIO(driver.get_screenshot_as_png())) as img :
  with remove_color(img, 0xffffffff) as img2:
    img2.save(r"C:\temp\screenshot.png")
Run Code Online (Sandbox Code Playgroud)

但是,如果页面内容中有一些白色像素,则最终可能会出现一些意外的透明像素,并且抗锯齿可能会可见。

另一个解决方案是将DevTool API与Chrome结合使用,以从屏幕快照中排除背景:

from selenium import webdriver
import json

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)
  if response['status']: raise Exception(response.get('value'))
  return response.get('value')

options = webdriver.ChromeOptions()
options.add_argument("disable-gpu")
options.add_argument("disable-infobars")

driver = webdriver.Chrome(chrome_options=options)
driver.get("http://www.bbc.co.uk/news")

# take screenshot with a transparent background
send("Emulation.setDefaultBackgroundColorOverride", {'color': {'r': 0, 'g': 0, 'b': 0, 'a': 0}})
driver.get_screenshot_as_file(r"C:\temp\screenshot.png")
send("Emulation.setDefaultBackgroundColorOverride")  # restore
Run Code Online (Sandbox Code Playgroud)