使用python实现对元素的长截图功能


Posted in Python onNovember 14, 2019

一.目标

浏览网页的时候,看见哪个元素,就能截取哪个元素当图片,不管那个元素有多长

使用python实现对元素的长截图功能 

二.所用工具和第三方库

python ,PIL,selenium

pycharm

三.代码部分

长截图整体思路:

1.获取元素

2.移动,截图,移动,截图,直到抵达元素的底部

3.把截图按照元素所在位置切割,在所有图片中只保留该元素

4.拼接

如果driver在环境变量中,那么不用指定路径

b=webdriver.Chrome(executable_path=r"C:\Users\Desktop\chromedriver.exe")#指定一下driver
b.get("https://www.w3school.com.cn/html/html_links.asp")
b.maximize_window()#最大化窗口

打开网站

使用python实现对元素的长截图功能 

我们可以看见一个ID为maincontent的元素,宽度为850PX,长度为3828PX,这个长度必须使用才能长截图才能完整截下来

el=b.find_element_by_id("maincontent")#找到元素

我们还需要一个重要的参数,就是你电脑一次能截取多高的像素

先用下图代码获取一个图片

#fp为存放图片的地址
b.get_screenshot_as_file(fp)

使用python实现对元素的长截图功能 

也就是说用我电脑上截图的默认高度为614像素

所以我设置一个变量:

sc_hight=614

然后设置一下其他变量

count = int(el.size["height"] / sc_hight) # 元素的高度除以你每次截多少就是次数
  start_higth = el.location["y"] # 元素的初始高度
  max_px = start_higth + (count - 1) * sc_hight # for循环中最大的px
  last_px = el.size["height"] + start_higth - sc_hight # 元素最底部的位置
  surplus_px = last_px - max_px # 剩余的边的高度
  img_path = [] # 用来存放图片地址

注释:

1.count为元素的高度/每次截取的高度,比如这次实例中元素高度为3828PX,我每次截614px,需要6.2次,int之后变成6,也就是截6次,还剩一点,那一点后面再说

2.start_higth为初始高度,这个没有什么可说的

3.max_px为循环结束后,到达的高度

4.last_px为元素最底部的高度

5.surplus_px就是移动6次后,还没有截取的高度

屏幕每次移动,移动sc_hight个像素,初始位置为(0,元素的Y值)

for i in range(0, count):
    js = "scrollTo(0,%s)" % (start_higth + i * sc_hight) # 用于移动滑轮,每次移动614px,初始值是元素的初始高度
    b.execute_script(js) # 执行js
    time.sleep(0.5)
    fp = r"C:\Users\wdj\Desktop\%s.png" % i # 图片地址,运行的话,改一下
    b.get_screenshot_as_file(fp) # 屏幕截图,这里是截取是完整的网页图片,你可以打断点看一下图片
    img = Image.open(fp=fp)
    img2 = img.crop((el.location["x"], 0, el.size["width"] + el.location["x"], sc_hight)) # 剪切图片
    img2.save(fp) # 保存图片,覆盖完整的网页图片
    img_path.append(fp) # 添加图片路径
    time.sleep(0.5)
    print(js)
  else:
    js = "scrollTo(0,%s)" % last_px # 滚动到最后一个位置
    b.execute_script(js)
    fp = r"C:\Users\wdj\Desktop\last.png"
    b.get_screenshot_as_file(fp)
    img = Image.open(fp=fp)
    print((el.location["x"], sc_hight - surplus_px, el.size["width"] + el.location["x"], sc_hight))
    img2 = img.crop((el.location["x"], sc_hight - surplus_px, el.size["width"] + el.location["x"], sc_hight))
    img2.save(fp)
    img_path.append(fp)
    print(js)

上面是把该元素的在页面都截完,并且剪切,把图片保存的路径放入img_path

最后一步:把所有截图都贴到新创建的图片中

new_img = Image.new("RGB", (el.size["width"], el.size["height"])) # 创建一个新图片,大小为元素的大小
  k = 0
  for i in img_path:
    tem_img = Image.open(i)
    new_img.paste(tem_img, (0, sc_hight * k)) # 把图片贴上去,间隔一个截图的距离
    k += 1
  else:
    new_img.save(r"C:\Users\wdj\Desktop\test.png") # 保存

运行效果图:

使用python实现对元素的长截图功能 

说明完整的截取下来了

补充优化:

如果是个小元素怎么办,不用长截图就能截取的那种

因为很简单我就直接贴代码了

start_higth = el.location["y"]
  js = "scrollTo(0,%s)" % (start_higth)
  b.execute_script(js) # 执行js
  time.sleep(0.5)
  fp = r"C:\Users\wdj\Desktop\test.png" # 图片地址,运行的话,改一下
  b.get_screenshot_as_file(fp)
  img = Image.open(fp=fp)
  img2 = img.crop((el.location["x"], 0, el.size["width"] + el.location["x"], el.size["height"])) # 剪切图片
  img2.save(fp)

效果如下:

使用python实现对元素的长截图功能 

完整代码:

from selenium import webdriver
from PIL import Image
import time
def short_sc(el,b):
  start_higth = el.location["y"]
  js = "scrollTo(0,%s)" % (start_higth)
  b.execute_script(js) # 执行js
  time.sleep(0.5)
  fp = r"C:\Users\wdj\Desktop\test.png" # 图片地址,运行的话,改一下
  b.get_screenshot_as_file(fp)
  img = Image.open(fp=fp)
  img2 = img.crop((el.location["x"], 0, el.size["width"] + el.location["x"], el.size["height"])) # 剪切图片
  img2.save(fp)
def long_sc(el,b):
  count = int(el.size["height"] / sc_hight) # 元素的高度除以你每次截多少就是次数
  start_higth = el.location["y"] # 元素的初始高度
  max_px = start_higth + (count - 1) * sc_hight # for循环中最大的px
  last_px = el.size["height"] + start_higth - sc_hight # 元素最底部的位置
  surplus_px = last_px - max_px # 剩余的边的高度
  img_path = [] # 用来存放图片地址
  for i in range(0, count):
    js = "scrollTo(0,%s)" % (start_higth + i * sc_hight) # 用于移动滑轮,每次移动614px,初始值是元素的初始高度
    b.execute_script(js) # 执行js
    time.sleep(0.5)
    fp = r"C:\Users\wdj\Desktop\%s.png" % i # 图片地址,运行的话,改一下
    b.get_screenshot_as_file(fp) # 屏幕截图,这里是截取是完整的网页图片,你可以打断点看一下图片
    img = Image.open(fp=fp)
    img2 = img.crop((el.location["x"], 0, el.size["width"] + el.location["x"], sc_hight)) # 剪切图片
    img2.save(fp) # 保存图片,覆盖完整的网页图片
    img_path.append(fp) # 添加图片路径
    time.sleep(0.5)
    print(js)
  else:
    js = "scrollTo(0,%s)" % last_px # 滚动到最后一个位置
    b.execute_script(js)
    fp = r"C:\Users\wdj\Desktop\last.png"
    b.get_screenshot_as_file(fp)
    img = Image.open(fp=fp)
    print((el.location["x"], sc_hight - surplus_px, el.size["width"] + el.location["x"], sc_hight))
    img2 = img.crop((el.location["x"], sc_hight - surplus_px, el.size["width"] + el.location["x"], sc_hight))
    img2.save(fp)
    img_path.append(fp)
    print(js)
  new_img = Image.new("RGB", (el.size["width"], el.size["height"])) # 创建一个新图片,大小为元素的大小
  k = 0
  for i in img_path:
    tem_img = Image.open(i)
    new_img.paste(tem_img, (0, sc_hight * k)) # 把图片贴上去,间隔一个截图的距离
    k += 1
  else:
    new_img.save(r"C:\Users\wdj\Desktop\test.png") # 保存
b=webdriver.Chrome(executable_path=r"C:\Users\wdj\Desktop\chromedriver.exe")#指定一下driver
b.get("https://www.w3school.com.cn/html/html_links.asp")
b.maximize_window()#最大化窗口
# b.get_screenshot_as_file(fp)
sc_hight=614#你屏幕截图默认的大小,可以去截一张,去画图里面看看是多少像素,我这里是614像素
# b.switch_to.frame(b.find_element_by_xpath('//*[@id="intro"]/iframe'))
el=b.find_element_by_id("maincontent")#找到元素
if el.size["height"]>sc_hight:
  long_sc(el,b)
else:
  short_sc(el,b)

完整代码

PS:

有些特殊情况,比如截取的元素在iframe中,直接用driver.switch_to.frame(iframe元素)即可

或者不是iframe,但是元素有overflow属性,直接用JS把他的overflow去掉就行

Python 相关文章推荐
python实现SMTP邮件发送功能
Jun 16 Python
python实现字典(dict)和字符串(string)的相互转换方法
Mar 01 Python
Python实现手写一个类似django的web框架示例
Jul 20 Python
python3实现指定目录下文件sha256及文件大小统计
Feb 25 Python
详解用python生成随机数的几种方法
Aug 04 Python
PyQt5 closeEvent关闭事件退出提示框原理解析
Jan 08 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
Apr 01 Python
pycharm 2018 激活码及破解补丁激活方式
Sep 21 Python
Python实现一个简单的毕业生信息管理系统的示例代码
Jun 08 Python
Python中Yield的基本用法
Oct 18 Python
Python APScheduler执行使用方法详解
Dec 10 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
Jan 06 Python
Pycharm创建项目时如何自动添加头部信息
Nov 14 #Python
python3实现单目标粒子群算法
Nov 14 #Python
python socket 聊天室实例代码详解
Nov 14 #Python
python中dict()的高级用法实现
Nov 13 #Python
python实现的多任务版udp聊天器功能案例
Nov 13 #Python
利用python实现PSO算法优化二元函数
Nov 13 #Python
使用python制作一个解压缩软件
Nov 13 #Python
You might like
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
2014/06/19 PHP
laravel 获取某个查询的查询SQL语句方法
2019/10/12 PHP
基于laravel缓冲cache的用法详解
2019/10/23 PHP
jquery中防刷IP流量软件影响统计的一点对策
2011/07/10 Javascript
11个用于提高排版水平的基于jquery的文字效果插件
2012/09/14 Javascript
JS 获取鼠标左右键的键值方法
2014/10/11 Javascript
jQuery文字横向滚动效果的实现代码
2016/05/31 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
Web打印解决方案之证件套打的实现思路
2016/08/29 Javascript
微信小程序 Storage API实例详解
2016/10/02 Javascript
纯JS实现轮播图
2017/02/22 Javascript
JS判断一个数是否是水仙花数
2017/06/11 Javascript
基于Bootstrap的标签页组件及bootstrap-tab使用说明
2017/07/25 Javascript
Node.js dgram模块实现UDP通信示例代码
2017/09/26 Javascript
vue实现商城购物车功能
2017/11/27 Javascript
详解webpack4之splitchunksPlugin代码包分拆
2018/12/04 Javascript
VUE路由动态加载实例代码讲解
2019/08/26 Javascript
JS 遍历 json 和 JQuery 遍历json操作完整示例
2019/11/11 jQuery
JavaScript实现HSL拾色器
2020/05/21 Javascript
[06:07]DOTA2-DPC中国联赛3月5日Recap集锦
2021/03/11 DOTA
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
pandas读取CSV文件时查看修改各列的数据类型格式
2019/07/07 Python
python2 中 unicode 和 str 之间的转换及与python3 str 的区别
2019/07/25 Python
Python定时任务APScheduler原理及实例解析
2020/05/30 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
css3实现文字扫光渐变动画效果的示例
2017/11/07 HTML / CSS
html5视频播放_动力节点Java学院整理
2017/07/13 HTML / CSS
附答案的Java面试题
2012/11/19 面试题
网络工程师专家职业发展路线
2014/02/14 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
《沙漠中的绿洲》教学反思
2014/04/24 职场文书
集中整治工作方案
2014/05/01 职场文书
Java 中的 Unsafe 魔法类的作用大全
2021/06/26 Java/Android
Win11安全功能升级:内置防网络钓鱼功能
2022/04/08 数码科技
MySQL 原理优化之Group By的优化技巧
2022/08/14 MySQL