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截取整个页面图片时,该如何操作呢?
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的浏览器只能截取可视区域的截屏,解决方法就是滚动截取+拼接的方式来实现。
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可能不兼容。所以上面的这种方式只是一个备选。