Python3第三方组件最新版本追踪实现

一、说明

在安全基线中有一项要求就是注意软件版本是否是最新版本,检查是否是最新版本有两方面的工作一是查看当前使用的软件版本二是当前使用软件的最新版本。在之前的“安全基线自动化扫描、生成报告、加固的实现(以Tomcat为例)”中只是做了前一项把当前使用的软件版本查出来,并没有做当前使用软件的最新版本。

当然其实这也是没办法的事,因为基线扫描一般而言都是离线扫描,而追踪最新版本肯定需要联网查询;一般就一个应用来说,少说也会用到几十个第三方库,我们不如索性把最新版本追踪功能单独独立出来实现。

追踪最新版本,直观上就只是从监测页面上把最新版本提取出来没有什么难度,但实际上总有一些坑所以还是值得提一提;另外自己一般重思路胜于重具体形式,所以某个功能用什么函数具体怎么实现就算写时很熟事后也经常忘记每次都得重新百度,所以也需要记一记。

二、新版本追踪实现难点及处理办法

2.1 确认需要的内容在哪个请求中返回

现在越来越多网站是restful的,所以当你打开某个url看到的内容并不一定直接是该url的请求中返回的;而爬虫工具(如requests)只会执行给定的请求(顶多会重定向一下),并不会解析和执行javascript进行后续相关联的请求,所以我们第一步要确认我们要提取的内容是在哪个请求中返回的。

确定的方法推荐直接使用开发者工具的Network选项卡,比如Nginx中我们要提取最新stable版本,操作如下:

2.2 禁用javascript防止页面调整

有些页面返回后会被javascript调整(比如原来在div[3]的内容),我们前面也说过爬虫工具一般不会分析和执行javascript,如果任由浏览器执行javascript那么浏览器的内容将和爬虫工具中的内容不一致,这将会导致后续从浏览器获取的提取路径不适用于爬虫工具,所以我们需要在浏览器中禁用javascript。

chrome禁用方式:设置----高级----内容设置----JavaScript----已屏蔽

firefox禁用方式:打开about:config----过滤出javascript.enabled项----在其上双击将其值设为false

2.3 获取标签提取路径

提取标签通常有css selector和xpath selector两种形式。手动去分析确定css和xpath表达式那是比较费劲的,因为比如在<body>和你的目标标签中间有一个<div>标签有id,人工去看一是代码很长不一定能注意到,二是就算注意到了你还得确定你的目标标签是不是这个<div>的内部。

有一有一种快速的方式能获取css和xpath表达式呢,答案是有的,chrome和firefox的开发者工具就集成了。先选中目标内容,然后在其上右键,最后“Copy XPath”即可。

firefox和chrome的区别是,firefox耿直一些xpath都是绝对路径,chrome智能一些如果中间有标签有id则会使用该标签做跳板,也因此一般个人喜欢用chrome的多一些。

2.4 requests_html与lxml.html在xpath上的区别

个人喜欢用xpath胜于css,python实现xpath上通常有requests_html和lxml.html两种形式,个人又喜欢requests_html多一点。

一是requests_html天然与requests相集成;二是requests_html筛选出来的标签可以直接查看其html内容而lxml.html需要使用tostring(element)方法(from lxml.html import tostring)打印才能看到标签的html内容;三是requests_html筛选出标签后该标签即以当前自己html的最外层标签作为根节点,而lxml.html不管怎么筛选始终以最初的那个标签为根结点即直接使用xpath("//a")出来的不是当前节点下的所有a标签而是最始页面下的所有a标签,虽然可以使用xpath(".//a")的形式作折中但总是不太符合直接的认识。

当然,可以看到在代码中我们也用到了lxml.html,所以lxml.html也不是一无是处,其用处就是使用requests_html解析github的releases页面始终提取不到标签而lxml.html可以。

2.5 反爬虫----User-Agent监测

不管是爬虫还是其他一些攻击工具,出于道义,在实现时他们都会在User-Agent标识是自己(比如requests的User-Agent形如“User-Agent: python-requests/2.22.0”)。部分网站会监测User-Agent头,如果发现不是常规的浏览器会禁止访问或返回不一样的内容。

而不管是爬虫还是其他一些攻击工具,出于实用,在实现时他们都会提供一个参数来修改User-Agent。所以应对User-Agent监测,我们只要使用相应参数把当前工具的User-Agent修改成和正常浏览器一样的User-Agent即可。

应该来说监测版本号只需要访问一两个页面,不会发起大量请求,所以也就不会触发大量访问时针对User-Agent的限制规则,但为了统一我们这里还是使用随机User-Agent的方式。

我们这里通过给headers[“User-Agent”]赋值覆盖原先requests的User-Agent;另外注意我们这里的用词,不是自定义的headers替换原先的headers而只是自定义的headers项去覆盖原先的headers的项,也就是说如果原先的headers存在的头如果自定义的headers中没重新赋值那该头部就仍保持原先的值(而不是就没了)。

总的代码逻辑如下:

user_agents = [
    ‘Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36‘,
    ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0‘,
    ‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36‘
]

headers["User-Agent"] = select_one_user_agent()

response = session.get(url, headers=headers, verify=False)

2.6 反爬虫----页面内容会随时间变化

实际追踪中发现网站www.elastic.co页面标签的id值会随时间变化,比如前几分钟返回的标签的id可能是“react-tabs-13165”,但过几分钟再访问可能就变成了“react-tabs-12345”。

这时如果是使用chrome获取xpath,chrome会以该id为跳板(如“//*[@id="react-tabs-13165"]/div[1]/div[1]/div[2]”),这个表达式在这几分钟可能是对的,但再过几分钟就提取不到想要的内容了。我这里的处理办法是直接使用firefox的绝对路径形式。

2.7 请求超时处理

请求超时抛出异常是很常见的,我们一是不能说任由异常抛出致使程序中断,二是不能说当前页面请求超时了就直接跳过;应当的做法是继续请求当前页面直到成功。

我这是使用捕获异常就再次递归的方式进行处理,推荐封装成一个函数,然后所有url请求都使用该函数实现,这样就不会有多处url请求然后多处都要进行处理了。

def get_url_response(url):
    session = HTMLSession()
    print(f"request start: {url}")
    try:
        response = session.get(url, headers=headers, verify=False)
    except:
        print(f"request error, will to try again: {url}")
        # 如果异常递归调用
        return get_url_response(url)
    print(f"request success: {url}")
    session.close()
    # 最终的出口只有这一个
    return response

2.8 最新版本提取的五种情况

第一种----页面只有一个系列只有一个版本,直接提取。比如nginx,最新的稳定版本总在下图那个标签那里,每次只要提取该标签的内容即可得到最新的稳定版本。

第二种----有时间顺序有多个版本只有一个分支,直接提取第一个(或最后一个)。比如mycat只有一个分支,其最后发布的版本一定是其最新版本,所以我们每次只要去读取其最新发布的那个位置就能获取到他的最新版本。

第三种----有时间顺序有多个版本有多个分支,取出版本字符串各系统取找到的第一个。比如ceph,从上往下第一个12.x版本就是12系列的最新版本,所以找到第一个包含"v12."字眼的直接return即可;其他13系列14系统一样。但这种方法如果新出一个系列那会漏掉(如v16系列)

第四种----没有时间顺序有多个版本只有一个分支,那就从所有版本号字符串中提取出版本号进行比较,选出最大的那个版本号。版本号比较说明见“Python3版本号比较代码实现”。

第五种----没有时间顺序有多个版本有多个分支,这种情况就先筛选出系列,然后各系列进行版本号比较即可。

2.9 读写excel文件

python操作excel其他不懂但感觉openpyxl就挺好用,下面简单说一下使用方法:

import openpyxl

# 一、文件操作
# 创建一个新的excel文件
mywb = openpyxl.Workbook()
# 打开一个已有excel文件,返回的对象与创建新excel文件一样
mywb = openpyxl.load_workbook(‘test.xlsx‘)

# 二、表操作
# 查看当前excel文件的所有表
mywb.get_sheet_names()
# 创建新表,test_sheet是新创建的表的表名
mysheet = mywb.create_sheet("test_sheet")
# 获取已有表对象,返回的对象与创建新表一样
# test_sheet改成自己要获取的表的表名
mysheet = mywb.get_sheet_by_name("test_sheet")

# 三、表内容操作
# 查看指定单元格内容,以A3单元格为例
mysheet["A3"].value
# 修改指定单元格内容,以A3单元格为例
mysheet["A3"] = "new value"

# 四、保存excel文件
# test.xlsx改成自己想要的名字
# 比较不符合认知的是,即便mywb是打开已有文件得来的也要有文件名参数
mywb.save("test.xlsx")

三、代码实现

3.1 目录结构说明

||--Common.py--公共函数文件||--Config.py--配置文件||--LibExample.xlsx--版本监测示例文件||--LibLatestVersionTracer.py--最新版本追踪实现的主要文件,一个库一个函数,名字形如"xxx_latest_version_tracer()"||--README.md--说明文件

3.2 环境构建

语言:Python3

依赖库:pip install requests-html lxml openpyxl

使用:python LibLatestVersionTracer.py

源代码:https://github.com/PrettyUp/LibLatestVersionTracer

3.3 实现效果演示

原始输入excel表格如下(其实并不从中读取数据用处只是帮助定位后边的最新版本和链接应输出到哪):

运行程序后新输出表格如下,新填写了Latest Version和Monitor URL列。(要强调我这里不是随便按格式写个库在上边,运行程序然后就得出了其最新版本和版本监测URL,那就成玄学了;每个库都得自己写代码实现追踪的):

原文地址:https://www.cnblogs.com/lsdb/p/11050005.html

时间: 2024-11-08 07:59:33

Python3第三方组件最新版本追踪实现的相关文章

Android应用之最新版本SDKV2.4实现QQ第三方登录

为什么要写这篇博客呢?因为,我在做这个第三方登录的时候,找了很多资料,发现要么就是过时了,要么就是说的很不清楚,很罗嗦,而且很多都是一些小 demo,不是什么实例,甚至连腾讯官方的文档都有这个问题,文档中很多地方用的不是最新的sdk写的示例,用最新版本的sdk发现根本没法达到预期的效 果,很多api已经发生了变化,demo还是用的原来的api中的方法,最坑爹是demo下载下来还要一个支持的库文件,但是sdk中又没有提供.. 自己跌跌撞撞,查找资料,整合,弄了几个小时,终于把它给整出来了,用在了开

Android应用之——最新版本SDK V2.4实现QQ第三方登录

为什么要写这篇博客呢?因为,我在做这个第三方登录的时候,找了很多资料,发现要么就是过时了,要么就是说的很不清楚,很罗嗦,而且很多都是一些小demo,不是什么实例,甚至连腾讯官方的文档都有这个问题,文档中很多地方用的不是最新的sdk写的示例,用最新版本的sdk发现根本没法达到预期的效果,很多api已经发生了变化,demo还是用的原来的api中的方法,最坑爹是demo下载下来还要一个支持的库文件,但是sdk中又没有提供.. 自己跌跌撞撞,查找资料,整合,弄了几个小时,终于把它给整出来了,用在了开发的

mac下安装Python3.*(最新版本)

前言:mac系统自带python,不过以当前mac系统的最新版本为例,自带的python版本都是2.*版本,虽然不影响老版本项目的运行,但是python最新的3.*版本的一些语法与2.*版本并不相同,网上的教程大神们也肯定都更新出了最新版的教程,我们不论是学习还是使用,当然用最新版会更好一点. 转载请注明出处http://www.cnblogs.com/meng1314-shuai/p/9031686.html 1.在安装最新版Python3.*之前,我们先熟悉一下系统自带的python.  M

mac 默认设置python3最新版本环境变量

前言:如果你是通过brew安装python3的话,目前最新版本是python3.7. 此时输入python,回车,如下图还是默认python2.7老版本 当然你也可以输入python3,回车,如下图为最新安装的python3.7新版本 作为一个间歇性强迫症及完美主义早期患者,还是想让python命令默认使用最新的python3,最简单的设置如下: 命令行执行:sudo vi /etc/paths 新增文件第一行为:/usr/local/opt/python/libexec/bin :wq 保存并

mac下安装Python3.7(最新版本)

前言:mac系统自带python,不过以当前mac系统的最新版本为例,自带的python版本都是2.版本,虽然不影响老版本项目的运行,但是python最新的3.版本的一些语法与2.*版本并不相同,网上的教程大神们也肯定都更新出了最新版的教程,我们不论是学习还是使用,当然用最新版会更好一点. 1.在安装最新版Python3.*之前,我们先熟悉一下系统自带的python. Mac系统自带python路径为/System/Library/Frameworks/Python.framework/Vers

Visual Studio 2017 RC 下载 最新版本的发行说明

我们非常荣幸地宣布 Visual Studio 2017 RC 现已推出! 此新版本包括我们最新的功能创新和改进. 注意 这里是 Visual Studio 2017 最新版本的发行说明. 下载:Visual Studio Enterprise 2017 RC 若要了解有关其他相关下载的详细信息,请参阅下载页. 另请参阅 Visual Studio 2017 系统要求和 Visual Studio 2017 平台目标以及兼容性. 重要事项 虽然一般情况下支持在生产环境中使用 Visual Stu

RedHat 6.5部署nginx并升级至最新版本

1 nginx基础知识 1.1 nginx简介 Nginx("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器.目前官方 Nginx 并不支持 Windows,只能在Linux.UNIX.BSD 系统下安装和使用.Nginx 本身只是一个 HTTP 和反向代理服务器,它无法像 Apache 一样通过安装各种模块来支持不同的页面脚本,例如 PHP.CGI 等. 1.2 nginx功能 Nginx 支持简单的负载均衡和

【FastDev4Android框架开发】打造QQ6.X最新版本侧滑界面效果(三十八)

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50253925 本文出自:[江清清的博客] (一).前言: 这两天QQ进行了重大更新(6.X)尤其在UI风格上面由之前的蓝色换成了白色居多了,侧滑效果也发生了一些变化,那我们今天来模仿实现一个QQ6.X版本的侧滑界面效果.今天我们还是采用神器ViewDragHelper来实现,之前我们以前基于ViewDragHelper的使用和打造QQ5.X效果了,基本使用方法可以点

libvirt最新版本未deploy到maven中央仓库

libvirt是虚拟化API. org.libvirt:libvirt:jar是其java实现. 官网:http://libvirt.org/ 在中央仓库搜索,其最高版本为0.4.7,可是现实情况这个不是最新版本(发现有人在用0.4.9版本) 通过查看其官网,在http://libvirt.org/java.html页面获得相关信息: MavenUp until version 0.4.7 the Java bindings were available from the central mav