使用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)
浙公网安备 33010602011771号