python-3.x - 通过 Selenium 使用 headless ChromeDriver 的透明屏幕截图

标签 python-3.x selenium selenium-chromedriver

据我了解,ChromeDriver 本身不会设置背景,CSS 会。因此,如果背景是透明的,为什么我没有得到透明的屏幕截图?
这是所谓的透明网站的屏幕截图:
Transparent background
相同的屏幕截图,但背景中有一个红色 div 以显示透明度应位于的位置:
Red background
这是我的代码:

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()
我如何才能创建该屏幕截图的透明版本?
*** 编辑 ***
我简要说明了我是如何做到这一点的。接受的答案帮助我达到了我可以弄清楚的地步,这就是我想要的。然而,这个要点是我的问题的正确解决方案:
https://gist.github.com/colecrtr/f58834ff09ab07e3c1164667b753e77a

最佳答案

一种方法是通过将 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")

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

另一种解决方案是在 Chrome 中使用 DevTool API 从屏幕截图中排除背景:

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

关于python-3.x - 通过 Selenium 使用 headless ChromeDriver 的透明屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46656622/

相关文章:

python - 从集合中删除满足谓词的所有元素

python-3.x - 属性错误 : module 'cv2.cv2' has no attribute 'release'

ruby - 对具有不同子域的多个网站运行 selenium 测试

selenium-chromedriver - 管理员禁止加载解压扩展

python - 如何在 Firefox 或 Chrome 中使用 Selenium webdriver 更改屏幕截图的目标目录

selenium - 管理 Selenium 网格队列

Python 3.x - 使用 sum 函数连接列表中的字符串

python - 将自定义变量/统计信息添加到 tqdm 栏

javascript - 使用 Protractor -webdrivers 的 Safari 历史导航中的未知错误

python - 简单的网页更改或按钮删除和抓取的数据是无用的