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截圖元素圖片
- 先截圖全螢幕
- 獲取具體元素的絕對位置資訊
- 根據位置資訊在全螢幕圖中裁剪
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截圖的全螢幕圖片背景色為透明色