selenium下對指定元素進行截圖

  • 2019 年 10 月 5 日
  • 筆記

Selenium本身是可以支援截圖的,包括全螢幕和元素的截圖;只是對於不用的瀏覽器的兼容性有差異而已。具體差異如下:

所以如果要想截取整個頁面的截圖,只有PhantomJS支援,而想要元素的截圖除了PhantomJS其它都支援。

driver = webdriver.Ie()  driver.maximize_window()  driver.get("https://www.autohome.com.cn")    driver.save_screenshot('capture.png')    #全螢幕截圖    ele = driver.find_element_by_id('s4612')  ele.screenshot('ele.png')    #元素截圖  

那麼如果想要在PhantomJS截圖元素圖片,在Chrome截取整個頁面圖片時,該如何操作呢?

PhantomJS截圖元素圖片

  1. 先截圖全螢幕
  2. 獲取具體元素的絕對位置資訊
  3. 根據位置資訊在全螢幕圖中裁剪
from selenium import webdriver  from PIL import Image    driver = webdriver.PhantomJS()  driver.maximize_window()    driver.get("https://www.autohome.com.cn")  driver.save_screenshot('capture.png')    #截取全螢幕    ele = driver.find_element_by_id('s4612')    #獲取元素位置資訊  left = ele.location['x']  top = ele.location['y']  right = left + ele.size['width']  bottom = top + ele.size['height']    im = Image.open('capture.png')  im = im.crop((left, top, right, bottom))    #元素裁剪  im.save('ele_capture.png')    #元素截圖    driver.quit()  

非PhantomJS截取全螢幕

非PhantomJS的瀏覽器只能截取可視區域的截屏,解決方法就是滾動截取+拼接的方式來實現。

from selenium import webdriver  from PIL import Image  import time  driver = webdriver.Firefox()  driver.maximize_window()    driver.get("https://www.autohome.com.cn")    script = '''      var viewHeight = document.documentElement.clientHeight;      var bodyHeight = document.body.scrollHeight;      return {'viewHeight': viewHeight, 'bodyHeight': bodyHeight};  '''  height_values = driver.execute_script(script)  default_name = 'capture_0.png'  driver.save_screenshot(default_name)  image_list = [(default_name, 0)]  image_width = 0    if height_values['viewHeight'] < height_values['bodyHeight']:   # 有滾動條      is_over = False      scrollY = 0        while not is_over:          script = '''              scrollTo(arguments[0], arguments[1]);          '''          x = 0          y = min(height_values['bodyHeight'] - scrollY, height_values['viewHeight'])          scrollY += y          fn = 'capture_%s.png' % scrollY          driver.execute_script(script, x, scrollY)          time.sleep(2)          driver.save_screenshot(fn)            if scrollY == height_values['bodyHeight']:              is_over = True              cropY = height_values['viewHeight'] - y                im = Image.open(fn)              image_width = im.width              im = im.crop((0, cropY, image_width, height_values['viewHeight']))              im.save(fn)            image_list.append((fn, scrollY))    if image_list:      merge_img = Image.new('RGB', (image_width, height_values['bodyHeight']), 0xffffff)        j = 0      for f, scrollY in image_list:          print(f)          img = Image.open(f)          merge_img.paste(img, (0, j))          j += height_values['viewHeight']      merge_img.save('merge.png')    driver.quit()  

上面的程式碼只能應付普通的長頁面,對於有動態載入內容的頁面需要動態獲取body的高度;另外不同的瀏覽器對於其中的js可能不兼容。所以上面的這種方式只是一個備選。

注意:

  • 在截圖過程中不要滾動頁面,否則截取的圖片可以有誤
  • PhantomJS截圖的全螢幕圖片背景色為透明色