金天牛

导航

使用python在selenium自动化中实现长截图

前言

在selenium自动化中,截图的功能是很简单的,一句代码就能实现。

driver.get_screenshot_as_file(pic_name)

问题

可当前却碰到另一个问题,一个页面在一个屏幕放不下,需要滑动才能逐步显示全,而我需要获取这个页面的所有显示作为一张图片,那只能使用长截图了

虽然长截图在很多工具上都提供了,但我自己怎么实现呢?

分析

所谓长截图,不过是当前页面在一个屏幕下显示不全,需要分几屏幕显示而已。那么我们要做的就是

1.算出页面的总长度

2.根据当前屏幕的高度,分析需要滑动几次才能在屏幕显示完

3.每次截取一屏,滑动后再截图

4.把所有截图进行拼接

思路如上,那么又该如何实现呢?这就需要用到我们的PIL库(python2),在python3中是pillow库

实现

我们使用一个函数来实现,在这个函数中,传入3个参数:

driver 是指webdriver

pic_name是指要传入的保存文件名

target_element是指到达什么元素停止截图,如果要截取页面所有,可以不用传入

bar_height表示顶部需要忽略的高度,以避免页面滑动时有些顶部元素不随页面滑动,需要忽略的情况。

 1 from selenium.webdriver.chrome.options import Options
 2 options = Options()
 3 options.add_experimental_option('excludeSwitches', ['enable-logging'])   # 禁用 Chrome 的日志输出
 4 driver = webdriver.Chrome(options=options)
 5 
 6 def get_long_pic_url(driver, pic_name, target_element=None, bar_height=0):
 7     # 获取页面总高度
 8     if target_element:
 9         total_height = target_element.location['y']
10     else:
11         total_height = driver.execute_script("return document.body.parentNode.scrollHeight")
12 
13     viewport_height = driver.execute_script("return window.innerHeight")
14 
15     # 计算需要截取的次数
16     viewport_height = viewport_height-bar_height
17     scrolls = total_height // viewport_height
18     if total_height % viewport_height != 0:
19         scrolls += 1
20 
21     # 创建空白画布
22     stitched_image = Image.new('RGB', (driver.get_window_size()['width'], total_height))
23     current_position = 0
24 
25     # 滚动并截取每一部分
26     for i in range(scrolls):
27         # 滚动到当前位置
28         driver.execute_script(f"window.scrollTo(0, {current_position})")
29 
30         # 等待滚动完成
31         time.sleep(0.5)
32 
33         # 获取当前视口的截图
34         screenshot = driver.get_screenshot_as_png()
35         img = Image.open(io.BytesIO(screenshot))
36 
37         # 如果当前是第一次截图,获取窗口高度
38         if i == 0:
39             effective_img = img
40         else:
41             # 截取从消息栏下方开始的部分
42             effective_img = img.crop((0, bar_height, img.width, img.height))
43 
44         # 将截图粘贴到画布上
45         stitched_image.paste(effective_img, (0, current_position))
46 
47         # 更新位置
48         current_position += effective_img.height
49 
50     # 保存拼接后的图片
51     pic_name = os.path.dirname(os.path.abspath(__file__)) + "\\img\\" + pic_name + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".png"  # 截图文件名
52     stitched_image.save(pic_name)
53     # print(f"拼接后的完整截图已保存至: {pic_name}")
54     pic_url = upload_file(pic_name)
55     return pic_url
56 
57 pic_url = get_long_pic_url(driver=driver, pic_name='cma', target_element=target_element, bar_height=100)

 

posted on 2025-08-11 14:40  金天牛  阅读(83)  评论(0)    收藏  举报