使用PaddleNLP进行恶意网页识别(七):网页二维码解析识别思路与实现
使用自动化测试工具selenium,zxing开源库,串联起在模拟沙盒上实现二维码的url解析、输入基于BERT网页标签序列分类,测试集准确率97%以上的模型进行识别的流程。
本文是《使用PaddleNLP进行恶意网页识别》系列第七篇,该系列持续更新中……
系列背景介绍:《使用PaddleNLP进行恶意网页识别》系列项目,围绕当前网络安全管理中面临的最大挑战之一——如何防止用户有益/无意中访问恶意网页,进而给企业造成损失的问题展开,尝试使用人工智能技术,针对此问题提出相应的解决方案。
系列还有一个姊妹篇,《使用PaddleNLP识别垃圾邮件》,欢迎感兴趣的读者点进来交流评论
系列目录
- 使用PaddleNLP进行恶意网页识别(一)
- 使用PaddleNLP的文本分类模型,做正常网页与被黑网页的简单二分类,根据HTML网页内容处理结果判断网页是否正常。
- 使用PaddleNLP进行恶意网页识别(二)
- 使用PaddleNLP的Ernie预训练模型Fine-tune,大幅提高根据HTML网页内容处理结果判断网页准确率。
- 使用PaddleNLP进行恶意网页识别(三)
- 使用PaddleNLP的文本分类模型,做正常网页与恶意网页的简单二分类,提取HTML标签信息判断网页是否正常。
- 使用PaddleNLP进行恶意网页识别(四)
- 尝试使用人工判断条件,设计提取HTML标签信息识别恶意网页的流程。
- 使用PaddleNLP的预训练模型Fine-tune,尝试提高提取HTML标签信息判断网页是否正常的效果。
- 将动态图训练的网页分类模型导出并使用Python部署。
- 使用PaddleNLP进行恶意网页识别(五)
- 该项目直接对标系列第二篇,对比BERT中文预训练模型和Ernie预训练模型在HTML网页内容分类流程和效果上的差异。
- 项目进一步完善和优化了HTML网页内容提取和数据清洗流程。
- 验证集上模型准确率可以轻松达到91.5%以上,最高达到95%,在BERT预训练模型上进行finetune,得到了目前在该HTML网页内容分类任务上的最好表现。
- 使用PaddleNLP进行恶意网页识别(六)
- 该项目直接对标系列第四篇,对比BERT中文预训练模型和Ernie预训练模型在HTML网页标签分类效果上的差异。
- 项目进一步完善和优化了HTML的tag内容提取和数据清洗流程。
- 验证集上模型准确率可以轻松达到96.5%以上,测试集上准确率接近97%,在BERT预训练模型上进行finetune,得到了目前在该HTML网页标签序列分类任务上的最好表现。
- 使用PaddleNLP进行恶意网页识别(七)
- 介绍了使用自动化测试工具selenium进行网页快照抓取的方法。
- 介绍了使用zxing开源库进行网页快照二维码定位和解析的方法。
- 介绍使用系列第六篇训练的模型,对二维码中包含的url网页链接进行识别分类的思路。
项目介绍
在前面的项目中,我们已经探索了基于给定的URL链接,获取网页HTLM标签和内容,进行恶意网页识别的方法。
但是,随着技术的发展,现在越来越多的网页链接将通过二维码传播,相关的安全隐患也随之而来,典型的,就有二维码内藏恶意URL的问题。
目前,大多数二维码承载的内容是一个URL,而现在的扫描软件往往不会对链接的安全性进行检测,恶意网址往往指向挂马网站、钓鱼网站、恶意软件安装链接等。用户一旦点击安装,手机就会感染病毒,有些甚至不需要安装就会中毒。另外,不法分子还会将跳转的网址伪装成官方网站,利用“钓鱼”的方式盗取用户账号、密码等信息,给用户的隐私安全和财产安全带来巨大的危害。
本项目探索的就是这类问题的解决方案。还是由易到难的思路,这里首先考虑的是,从PC端访问一个网页,获取这个网页上是否存在二维码,如果存在,能否对二维码内含的URL进行提取,再送入恶意网页识别模型中。
一、基于Selenium的网页快照抓取
1.1 关于Selenium
Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。
作为一款web自动化测试工具,Selenium有诸多有点:
- 免费
- 小巧,对于不同的语言它只是一个包而已
- 易用,支持多种编程语言
- 支持多平台:windows、linux、MAC ,支持多浏览器:ie、firefox、safari、opera、chrome
- 支持分布式测试用例的执行,可以把测试用例分布到不同的测试机器的执行,相当于分发机的功能
1.2 Selenium网页抓取操作
注意:以下操作要在本地环境完成
1.2.1 使用pip命令安装selenium
pip install selenium -i https://mirror.baidu.com/pypi/simple
Looking in indexes: https://mirror.baidu.com/pypi/simple
Collecting selenium
Downloading https://mirror.baidu.com/pypi/packages/80/d6/4294f0b4bce4de0abf13e17190289f9d0613b0a44e5dd6a7f5ca98459853/selenium-3.141.0-py2.py3-none-any.whl (904 kB)
|████████████████████████████████| 904 kB 3.2 MB/s
Requirement already satisfied: urllib3 in c:\users\kkcac\.conda\envs\paddle\lib\site-packages (from selenium) (1.25.8)
Installing collected packages: selenium
Successfully installed selenium-3.141.0
1.2.2 准备浏览器驱动
选择本地环境已经安装的浏览器驱动,比如笔者本地装的是Edge浏览器,就下载Edge浏览器驱动。
- Firefox浏览器驱动:geckodriver
- Chrome浏览器驱动:chromedriver , taobao备用地址
- IE浏览器驱动:IEDriverServer
- Edge浏览器驱动:MicrosoftWebDriver
- Opera浏览器驱动:operadriver
- PhantomJS浏览器驱动:phantomjs
需要把浏览器驱动放入系统路径中,或者直接告知selenuim的驱动路径。
1.2.3 编写网页快照爬取代码
from selenium import webdriver
import time
import os.path
def webshot(url,saveImgName):
# 指定浏览器驱动的路径,注意在Windows里要用\\表示
edgedriver = r"C:\\Users\\yourname\\Downloads\\edgedriver_win32\\msedgedriver.exe"
driver = webdriver.Edge(executable_path=edgedriver)
driver.maximize_window()
# 返回网页的高度的js代码
js_height = "return document.body.clientHeight"
picname = saveImgName
link = url
# driver.get(link)
try:
driver.get(link)
# k如果不是1,浏览器会自动往下滚动
k = 1
height = driver.execute_script(js_height)
while True:
if k * 500 < height:
js_move = "window.scrollTo(0,{})".format(k * 500)
print(js_move)
driver.execute_script(js_move)
time.sleep(0.2)
height = driver.execute_script(js_height)
k += 1
else:
break
scroll_width = driver.execute_script('return document.body.parentNode.scrollWidth')
scroll_height = driver.execute_script('return document.body.parentNode.scrollHeight')
driver.set_window_size(scroll_width, scroll_height)
driver.get_screenshot_as_file(picname + ".png")
print("Process {} get one pic !!!".format(os.getpid()))
time.sleep(0.1)
except Exception as e:
print(picname, e)
if __name__ == '__main__':
t = time.time()
# 两个参数,前面url,后面保存地址
webshot('http://www.baidu.com','C:\\Img\\scrapy_image')
print("操作结束,耗时:{:.2f}秒".format(float(time.time() - t)))
1.2.4 运行网页快照自动爬取代码
自动化测试运行过程,浏览器会自动打开
保存的快照结果
1.2.5 Selenium启动配置参数
如果是Chrome、Firefox、IE等浏览器,Selenium还提供了手动配置参数的功能,比如设置--headless
,可以让浏览器静默抓取快照,不用弹出。
相关内容可参考:selenium启动Chrome配置参数问题
最后,我们可以找一个网页,完成包含二维码的网页快照保存,相关结果放在scrapy_image.png
文件中。
二、基于Zxing开源库的二维码识别
2.1 OpenCV库QRCodeDetector模块的缺陷
关于二维码的检测和识别,可以用OpenCV库自带的QRCodeDetector
检测模块,参考项目:松哥带你20行代码进行二维码检测和识别
但是实际使用过程中,我们会发现,QRCodeDetector
检测模块这个检测模块,只能识别标准二维码,对比较复杂的二维码识别效果并不好,比如:
import cv2
import numpy as np
# 读取二维码
src = cv2.imread("scrapy_image.png")
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 设置检测器
qrcoder = cv2.QRCodeDetector()
# 检测识别二维码
codeinfo, points, straight_qrcode = qrcoder.detectAndDecode(gray)
# 输出识别二维码的信息
print("二维码所包含的信息是 : \n%s"% codeinfo)
二维码所包含的信息是 :
上面的结果说明,OpenCV库的QRCodeDetector模块,没能提取到上文图片中的二维码信息。
2.2 Zxing
ZXing是一个开源的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码,其中python-zxing是zxing的Python语言封装版本。它的安装和使用非常简单。
!pip install zxing
import zxing
reader = zxing.BarCodeReader()
barcode = reader.decode("scrapy_image.png")
print(barcode)
BarCode(raw='https://www.zhihu.com/account/scan/login/pgEsgIdySlmwHA5k', parsed='https://www.zhihu.com/account/scan/login/pgEsgIdySlmwHA5k', uri='file:///home/aistudio/scrapy_image.png', format='QR_CODE', type='URI', points=[(1233.5, 816.5), (1233.5, 573.5), (1476.5, 573.5), (1452.0, 792.0)])
barcode.raw
'https://www.zhihu.com/account/scan/login/pgEsgIdySlmwHA5k'
看来,Zxing果然很顺利地识别到了二维码中的信息,我们可以绘制定位点,查看更详细的识别效果。
result = cv2.drawContours(src, [np.int32(barcode.points)], 0, (0, 0, 255), 2)
cv2.imwrite('1.jpg',result)
True
%matplotlib inline
import matplotlib.pyplot as plt
# 加载彩色图
img = cv2.imread('1.jpg', 1)
# 将彩色图的BGR通道顺序转成RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 显示图片
plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f71d014e590>
三、与基于BERT的网页标签序列分类模型的整合
import requests
from bs4 import BeautifulSoup
# 将解析结果barcode.raw传入
r = requests.get(barcode.raw)
demo = r.text
soup=BeautifulSoup(demo,"html.parser")
tags = []
for tag in soup.find_all(True):
tags.append(tag.name)
data = []
data.append(','.join(tags))
# 网页标签序列提取结果
))
# 网页标签序列提取结果
data
['html,head,title,body,center,h1,hr,center']
将网页标签序列提取结果传入使用PaddleNLP进行恶意网页识别(六)的最后一小节,我们就基于在10万的正常和恶意HTML文件数据集的测试集上准确率达到97%的模型,完成了二维码的URL解析和检测分类流程串联。
label_map = {0: '恶意网页', 1: '正常网页'}
predictions = predict(model, data, tokenizer, label_map, batch_size=64)
for idx, text in enumerate(data):
print('预测网页: {} \n网页标签: {}'.format(barcode.raw, predictions[idx]))
更多推荐
所有评论(0)