利用 Python + Selenium 实现对页面的指定元素截图(可截长图元素)
对WebElement截图
WebDriver.Chrome自带的方法只能对当前窗口截屏,且不能指定特定元素。若是需要截取特定元素或是窗口超过了一屏,就只能另辟蹊径了。
WebDriver.PhantomJS自带的方法支持对整个网页截屏。
下面提供几种思路。
方式一
针对WebDriver.Chrome
通过WebDriver的js脚本注入功能,曲线救国。
注入第三方html转canvas的js库(见下方推荐)
获取元素html源码
将html转换为canvas
下载canvas
优点: 截取长图容易实现
缺点: 加载第三方库耗费时间,转换原理请参考这篇文章:
方式二
针对WebDriver.Chrome
截取全图,自行裁剪、拼接
获取元素位置、大小
获取窗口大小
截取包含元素的窗口
进行相应的裁剪和拼接。
具体算法思路很清晰,但需要注意的细节较多。这里就不在赘述。示例代码请移步:
优点: 不需太多js工作,python+少量js代码即可完成
缺点: 拼接等工作会被WebDriver的实现差异、图片加载速度等因素影响,需多加注意。 在保证截图质量的情况下,速度较慢
方式三
针对WebDriver.PhantomJS
由于接口实现的差异,PhantomJS相比于Chrome,可以截取到整个网页。所以获取指定元素的截图也就简单很多
截取网页全图
裁剪指定元素
driver = webdriver.Chrome()
driver.get('http://stackoverflow.com/')
driver.save_screenshot('screenshot.png')
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']
im = Image.open('screenshot.png')
im = im.crop((left, top, right, bottom))
im.save('screenshot.png')
优点: 实现简单
缺点: 对于高度太高的页面会导致文件过大,处理会有问题,我测试的最大图片尺寸是12.8M。
解决图片加载不完整的问题
参考: 利用 Python + Selenium 自动化快速截图
我们先在首页上执行一段 JavaScript 脚本,将页面的滚动条拖到最下方,然后再拖回顶部,最后才截图。这样可以解决像上面那种按需加载图片的情况。
# -*- coding: utf-8 -*-
from selenium import webdriver
import time
def take_screenshot(url, save_fn="capture.png"):
# browser = webdriver.Firefox() # Get local session of firefox
#谷歌浏览器截取当前窗口网页
chromedriver = r"C:\soft\chromedriver2.31_win32\chromedriver.exe"
browser = webdriver.Chrome(chromedriver)
#phantomjs截取整张网页
# browser = webdriver.PhantomJS()
browser.set_window_size(1200, 900)
browser.get(url) # Load page
#将页面的滚动条拖到最下方,然后再拖回顶部
browser.execute_script("""
(function () {
var y = 0;
var step = 100;
window.scroll(0, 0);
function f() {
if (y < document.body.scrollHeight) {
y += step;
window.scroll(0, y);
setTimeout(f, 100);
} else {
window.scroll(0, 0);
document.title += "scroll-done";
}
}
setTimeout(f, 1000);
})();
""")
for i in xrange(30):
if "scroll-done" in browser.title:
break
time.sleep(10)
browser.save_screenshot(save_fn)
browser.close()
if __name__ == "__main__":
take_screenshot("http://codingpy.com")
如何截取某个网页元素
有时候我们只想截取某个网页元素的图片呢?比如说会动态变化的验证码。本来 Selenium 也提供了对元素截图的支持,只要在选中的元素上调用其 screenshot() 方法即可。
但是在实际使用时却遇到了 Unrecognized command 这个异常,经过一段时间检索也没有找到解决办法。所以,只能曲线救国,利用 Selenium 执行JS代码,将页面上不需要的元素一一删除,只保留我们希望留下的元素,然后再利用上面的窗口截屏功能。
例如,如果我们只截取编程派网站右侧的二维码,可以执行这样一段JQuery代码:
$('#main').siblings().remove();
$('#aside__wrapper').siblings().remove();
$('.ui.sticky').siblings().remove();
$('.follow-me').siblings().remove();
$('img.ui.image').siblings().remove();
代码执行完毕之后,就只剩下二维码的图片了。然后我们再截屏。不过这样有一点不好,就是截屏图片的下方会有大量空白内容。
- 代码
# -*- coding: utf-8 -*-
from selenium import webdriver
import time
def take_screenshot(url, save_fn="capture.png"):
# browser = webdriver.Firefox() # Get local session of firefox
chromedriver = r"C:\soft\chromedriver2.31_win32\chromedriver.exe"
browser = webdriver.Chrome(chromedriver)
# browser = webdriver.PhantomJS()
browser.set_window_size(1200, 900)
browser.get(url) # Load page
#将页面的滚动条拖到最下方,然后再拖回顶部
# browser.execute_script("""
# (function () {
# var y = 0;
# var step = 100;
# window.scroll(0, 0);
#
# function f() {
# if (y < document.body.scrollHeight) {
# y += step;
# window.scroll(0, y);
# setTimeout(f, 100);
# } else {
# window.scroll(0, 0);
# document.title += "scroll-done";
# }
# }
#
# setTimeout(f, 1000);
# })();
# """)
#
# for i in xrange(30):
# if "scroll-done" in browser.title:
# break
# time.sleep(10)
#只截取编程派网站右侧的二维码,可以执行这样一段JQuery代码:siblings().remove()移除兄弟姐妹元素
browser.execute_script("""
$('#main').siblings().remove();
$('#aside__wrapper').siblings().remove();
$('.ui.sticky').siblings().remove();
$('.follow-me').siblings().remove();
$('img.ui.image').siblings().remove();
""")
browser.save_screenshot(save_fn)
browser.close()
if __name__ == "__main__":
take_screenshot("http://codingpy.com/article/take-screenshot-of-web-page-using-selenium/")
不同wewbdriver对某些方法的实现不同
Chrome和PhantomJS 的接口差异
抓知乎时的坑,
Chrome用
WebElement.text可以正常得到值,用PhantomJS只能用WebElement.get_attribute('innerHTML')WebDriver.Chrome截图只能截当前屏幕区域。WebDriver.PhantomJS截图可以获取整个页面的长图。
其它还有一些坑等待发现
推荐
利用 Python + Selenium 实现对页面的指定元素截图(可截长图元素)的更多相关文章
- Python + Selenium 实现对页面的指定元素截图(可截长图元素)【转载】
先在首页上执行一段 JavaScript 脚本,将页面的滚动条拖到最下方,然后再拖回顶部,最后才截图.这样可以解决那种按需加载图片的情况 以下代码为转载别处博客改造后的,有chrome和ff两种浏览器 ...
- Python+Selenium自动化-定位页面元素的八种方法
Python+Selenium自动化-定位页面元素的八种方法 本篇文字主要学习selenium定位页面元素的集中方法,以百度首页为例子. 0.元素定位方法主要有: id定位:find_elemen ...
- Python+Selenium自动化-获取页面信息
Python+Selenium自动化-获取页面信息 1.获取页面title title:获取当前页面的标题显示的字段 from selenium import webdriver import t ...
- selenium截屏操作(也支持截长图)
1.常用的可能是谷歌和火狐做自动化在抛异常的时候可以截屏保存 from selenium import webdriver br=webdriver.Chrome() br.maximize_wind ...
- 利用python+selenium在pycharm下进行页面登陆的半自动测试
很久没有写了,现在正式入职,准备好好干,加油! 我的第一个较正式的测试代码: from selenium import webdriverimport unittestimport sysimport ...
- 在CentOS下利用Python+selenium获取腾讯首页的今日话题。
1.安装依赖包 yum install wget firefox gcc zlib zlib-devel Xvfb 2.安装setuptools 官网地址:https://pypi.python.or ...
- Python+selenium点击网页上指定坐标
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains dr = ...
- python selenium 多个页面对象类使用同一个webdriver(即只打开一个浏览器窗口)
1 class BasePage(): 2 """selenium基类""" 3 4 def __init__(self, driver=N ...
- [Chrome Headless + Python] 截长图 (Take Full-page Screenshot)
# -*- coding: utf-8 -*- import time import os from selenium import webdriver from selenium.webdriver ...
随机推荐
- UITableView设置单元格选中后只显示一个打勾的三种简单方法(仅供参考)
1.第一种方法:先定位到最后一行,若选中最后一行直接退出,否则用递归改变上次选中的状态,重新设置本次选中的状态. - (UITableViewCell*)tableView:(UITableView* ...
- SharePoint 2013配置开发环境,需安装VS2012插件
SharePoint 2013已经安装好了,接下来就是配置开发环境,安装VS2012,但是,装好了以后,发现没有SharePoint 2013开发的支持,如下图: 然后,去网上查找资料,VS2012对 ...
- Mysql创建索引
1.索引作用 在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万倍. 例如,有 ...
- 直接执行SQL语句的快捷键是什么啊?嘎嘎
在查询中输入SQL语句后,执行语句的快捷键~ 分享到: 2009-10-23 10:59网友采纳 左键..嘿嘿,开个玩笑 你把鼠标移动到执行按钮上停一会就能看到了啊
- Unknown entity: org.jbpm.services.task.audit.TaskEventImpl
1. use this persistence.xml - simply copy it into src/main/resources/META-INF please note the name o ...
- Django的时区问题
在Django项目中,最好全部日期值都做成配时区信息的,但是由于遗留项目或者跨语言项目,其他语言的开发人员觉得时区信息处理太麻烦.如何在一个项目中同时适配带时区和不带时区的两种字段. 1.输出:不带时 ...
- JSF-页面导航
页面导航 1)导航处理涉及的术语: -动作值:触发动作事件的组件的action:EL方法表达式.字符串文字. -结果值:动作组件的action属性的:EL方法表达式的返回值.字符串文字:或结果组件的o ...
- C# 获取文件下载的各种方法
public class RemoteDownload { public static void DownLoad(string addressUrl,string localName) { //下载 ...
- Pascal Triangle
Description: Given numRows, generate the first numRows of Pascal's triangle. For example, given numR ...
- Flask构建微电影(一)
第一章.项目介绍 1.1.前言 本教程我将带领大家如何使用flask框架开发微电影网站.Flask是python中最受欢迎的轻量级web框架,flask扩展丰富,冗余度小,可自由选择组合各种插 ...