SVG反爬虫不同于字体反爬虫,它巧妙的利用css 与 svg的关系,将字符映射到网页中,看起来虽然正常,但是却抓取不到有效内容。本文带你深入浅出,破了SVG反爬虫的套路,学会之后,可应用于某点评网。

一、初识SVG反爬:

为了防止面对监狱编程,我在本地自己做了一个网页用于爬虫测试。任务是爬取票据中的产品价格信息,按照往常一样审查元素定位目标节点,但是发现事情并不简单。

看图:

¥符号后面并没有我们想要的价格信息,而是四个d标签取而代之。随便选中一个7,发现对应的是属性class=lhtqsc的d标签。

看css样式:

有两段描述这个标签的语句,第一段比较常规,但是其中的

background-image: url(../css/zhiliao.svg);

就有点奇怪,而第二段,描述的是background,它的值是两个 大小值,单位px。

打开svg文件查看:

貌似是没什么规律的数字查看该页面网页源代码,发现是张这样的:

二、什么是SVG?

想要搞定SVG反爬虫就得先搞清楚SVG:

SVG是一种基于xml用于描述矢量图的图形格式,由于矢量图放大或缩写都不会影响图形的质量,所以被较多的应用在web站点与APP中,常见的存在形式是图标。

编写一个SVG文件:

为了方便,我们可以把要写的svg,写到HTML文件中,新建一个svg.html键入如下内容:

<html><body><svg xmlns="http://www.w3.org/2000/svg" version="1.1">  <text x="0" y="15" fill="red">I love zhiliaotext>svg>body>html>

浏览器打开如下:其中:

<text x="0" y="15" fill="red">I love zhiliaotext>

很关键,这一行用text标签定义了一段文本,fill是文本颜色属性,为红色,并且指定了文本的坐标。该坐标的规则是:

  1. 以左上角为坐标系的原点(0,0)
  2. X 轴的正方向向右,从 0,0 点开始向右, x 逐渐增大。Y 轴的正方向向下,从 0,0 点开始向下, y 逐渐增大。
  3. 坐标以像素为单位
  4. n 个字符可以有 n 个位置参数。

增加一行:

<text x="10 20 30 40 50 60 70 80 90" y="100" fill="black">I love zhiliaotext>

这行代码指定了前九个字符的位置,且指定了文本的颜色,y的值也增大到100,浏览器打开如下:再次增加一行:

<text x="40 20 30 10 50 60 70 80 90" y="120" fill="red">I love zhiliaotext>

上图可以看到,在不改变文本顺序的情况下通过改变x中的值,让第一个字符I和第四个字符o交换了位置。

三、SVG与CSS的联系:

现在我们尝试把css和svg联系起来,更加深入的理解,方便我们做下一步抓取工作:在svg中,X轴正方向为从左到右,y轴的正方向是从上到下;在css中,X轴负数向右,Y轴是负数向下。一图胜千言:所以,CSS与SVG刚好相反。新建一个zhiliao.svg并键入:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="650px" height="230.0px"><style>text {font-family:PingFangSC-Regular,Microsoft YaHei,'Hiragino Sans GB',Helvetica;font-size:14px;fill:#666;}style>  <text x='10 20 30 10 50 60 70 80 90 100 110 120 130 140 150 160' y='30'>hello,zhiliaotext> svg>

我们在style中 定义了字符的风格,大小(14px),以及颜色(#666)。定义了每个字符所在的位置。现在我们对第一个字符h进行定位,X轴计算法则:字符大小 / 2 + 字符的x轴起点位置参数Y轴计算法则:(y 轴高度 - 字符 y 轴起点 - 字符大小)/ 2 + 字符 y 轴起点位置参数 + 字符大小数值的一半也就是:X = 14/2 + 0  = 7Y = (30 - 0 - 14) /  2  + 0 + 14 /  2 = 15svg中对应的定位就是 x = 7 ,y = 15css与svg相反,所以是 -7,-15现在新建一个zhiliao.css文件,键入如下内容:

d[class^="lht"] {  width: 14px;  height: 30px;  background-image: url(zhiliao.svg);  background-repeat: no-repeat;  display: inline-block;  vertical-align: middle;}.lhttest {  background: -7px -15px;}

新建一个demo.html,键入:

<html><head>    <link type="text/css" rel="stylesheet" href="zhiliao.css">head><body><d class="lhttest">d>body>html>

html中会引入css文件,css又会引入svg文件。通过d标签的class属性值读取css对应的svg标签,完成对svg的映射。然后把demo.html拖到浏览器,可以看到:字符h完完整整的被我们成功的映射出来了。搞懂了这些,反爬就不是难事了,我们要做的是让程序搞定这些。

四、Python抓取数据:

回到刚才的目标网站,开始实战抓取。

1.获取css样式文件与svg文件内容:
import reimport requestsfrom lxml import etreesvg_link  = "http://localhost/zhiliao_svg/css/zhiliao.svg"css_link  = "http://localhost/zhiliao_svg/css/style.css"#获取svg与css文件内容svg_text = requests.get(svg_link).text css_text = requests.get(css_link).text
2.获取匹配出class属性值对应css参数,与字符大小:
css_text = css_text.replace('\n', '').replace(' ', '') #将换行符与空格清除,方便下一步匹配#定义一个函数用于匹配class属性为xx对应的css参数def find_xy(in_text, class_value):    re_sentence =  '.%s{background:-(\d+)px-(\d+)px;}' % class_value    pattern = re.compile(re_sentence)    res = pattern.findall(in_text)    return res[0]#寻找出svg文件中定义的字符大小def find_font_size(in_text):    fs = re.compile(r'font-size:(\d+)px')    res = fs.findall(in_text)    return int(res[0])print(find_xy(css_text, "lhtqsc"), find_font_size(svg_text))

测试寻找class=lhtqsc的css对应参数和字符大小,输出如下:

('288', '141') 14

打开对应css与svg文件验证:一致,成功!

3.观察svg文件:

这里有四个text标签,对应四个文本,每个文本X轴都是从0开始,并且以14递增Y轴不相同的,分别是 38, 83 , 120 ,164文本顺序也有所不同。现在我们get这些数据:

soup = etree.HTML(svg_text).xpath("//text")list_y = [i.get('y') for i in soup]list_text = [i.text for i in soup]print(list_y)print(list_text)

输出:

['38', '83', '120', '164'] ['154669136497975167479825383996313925720573', '560862462805204755437571121437458524985017', '671260781104096663000892328440489239185923', '684431081139502796807382']

到这一步,我们成功的分别取出了y的和text标签的四个值,并组成了列表。但是,这些元素 几乎没有和 [‘38’, ‘83’, ‘120’, ‘164’] 中有相等的,这对于我们寻找text标签包含的文本值并不影响,我们找到最近接近的即可。我们仍然以 class=lhtqsc为例子,寻找它最近的y值,从而找出是哪个text标签包含的值。完善我们的代码:

soup = etree.HTML(svg_text).xpath("//text")list_y = [i.get('y') for i in soup] #找出所有的y值list_text = [i.text for i in soup]  #找出所有的text值svg_font_size = find_font_size(svg_text) #找出font-size值x, y = find_xy(css_text, "lhtqsc")       #找出class=lhtqsc的xy坐标real_y = [i for i in list_y if y <= i][-1]  #找出是哪一个 yreal_text = list_text[list_y.index(real_y)] #找出是那个一 textprint(real_text)

输出:

684431081139502796807382

然后就可以利用切片的特性寻找到对应的数值啦!

pos = int(x) // svg_font_sizeprint(real_text[pos])

输出 7,有图为证:验证:我们打开网站,看看对应的是不是数字7到这里,就算成功了,是不是很简单呢?跟我一起做一遍吧。需要本文完整所有的代码,请关注本公众号,然后发送“20512”即可获取本文中所有代码!- End -Python爬虫高级之JS渗透登录新浪微博 | 知了独家研究WTF?能把Python代码写得这么优雅的都是神仙程序员吧!Python协程还不理解?请收下这份超详细的异步编程教程!还没学会来找我!徐大sao吃了哪些好吃的?用Python生成词云,一目了然!性能是Flask的3倍!比PHP7还快!这个Python框架你值得拥有!(附使用教程)

svg text换行_5分钟看懂SVG反爬虫原理与绕过实战 | 知了干货分享相关推荐

  1. 画图用计算机显卡,1分钟看懂显卡显卡绘图原理!

    原标题:1分钟看懂显卡显卡绘图原理! 熟悉电脑的人都知道计算机里面有个东西叫做'显卡',无论是性能爆炸的独立显卡还是羸弱的核心显卡,其中之一是家用电脑必不可少的硬件之一. 其实在电脑里面所有的数据都是 ...

  2. nedc和epa续航里程什么意思_5分钟看懂综合工况续航、等速续航和NEDC续航指标

    首先,我想问大家几个关于电动汽车续航的小问题: 你觉得秦EV 300续航里程是多少?和宋EV300续航里程相同吗? 宋EV300续航比北汽EU260续航更远吗? 吉利2016年帝豪EV续航260km, ...

  3. python3 线程池源码解析_5分钟看懂系列:Python 线程池原理及实现

    概述 传统多线程方案会使用"即时创建, 即时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器 ...

  4. 今日头条的排名算法_3分钟看懂今日头条算法原理

    国内的各种渠道千千万,主流的广告平台不多也不算少. 而今日头条与其它平台最大区别在于--个性化推荐和智能分发. 可以简单理解为,今日头条上投放的广告,是通过"机器人代码"过滤再分发 ...

  5. 10分钟看懂 Java NIO 底层原理

    写在前面 很多的小伙伴,被java IO 模型,搞得有点儿晕,一会儿是4种模型,一会儿又变成了5种模型. 很多的小伙伴,也被nio这个名词搞晕了,一会儿java 的nio 不叫 非阻塞io,一会儿ja ...

  6. 三相逆变器双pi控制器参数如何调节_一分钟看懂维也纳三相整流器

    欢迎加入技术交流QQ群(2000人):电力电子技术与新能源 1105621549 高可靠新能源行业顶尖自媒体 在这里有电力电子.新能源干货.行业发展趋势分析.最新产品介绍.众多技术达人与您分享经验,欢 ...

  7. 量子计算机 漫画,漫画 | 10分钟看懂量子比特、量子计算和量子算法

    原标题:漫画 | 10分钟看懂量子比特.量子计算和量子算法 请做好准备,即将进入烧脑模式! 宏观世界的生活经验很多都是表象.比如,你可能认为世界的运行是确定的.可预测的:一个物体不可能同时处于两个相互 ...

  8. java和python的web自动化有什么区别-三分钟看懂Python和Java的区别

    随着人工智能的火爆,Python和Java一直在各种流行编程语言中名列前茅.其实Java和Python有些相似,因为很多编程语言之间是互通的.Java现在还是第一,不知道Python未来会不会超越Ja ...

  9. python和java一样吗-三分钟看懂Python和Java的区别

    随着人工智能的火爆,Python和Java一直在各种流行编程语言中名列前茅.其实Java和Python有些相似,因为很多编程语言之间是互通的.Java现在还是第一,不知道Python未来会不会超越Ja ...

最新文章

  1. 独家 | 手推贝叶斯分析:基于真实示例的贝叶斯分析分步演练
  2. 分分钟教会你使用HTML写Web页面
  3. maven版本高于idea
  4. 安卓笔记之配置第一个程序
  5. bash漏洞修补, CVE-2014-6271
  6. SQLServer还原 指定的转换无效解决方法
  7. 第一站---大连---看海之旅
  8. 在有序数列里插入新元素(C语言)
  9. Oracle数据库表中字段顺序的修改方法
  10. java 的单态模式(只可以创建一个对象)
  11. 有没有比python更简单的语言排名_编程语言4种更快更简单实现Python数据可视化的方法...
  12. 顺序存储结构与链式存储结构的比较
  13. 网站如何配置CDN加速?网站域名接入腾讯云CDN的步骤(附CDN防御)
  14. PHP结合redis实现秒杀活动大并发
  15. spring-boot-maven-plugin 爆红,分析原因并解决。
  16. 【66份】SaaS资料合集
  17. wps指定路径不存在怎么办_WPS说目录不存在
  18. php 视频分割,如何把一个视频分成两段或多段 视频切割软件
  19. LintCode 1256. 第n个数位 JavaScript算法
  20. 泰克Tektronix示波器软件TDS520|TDS1001|TDS1002上位机软件NS-Scope

热门文章

  1. Angular2.0 基础: Form
  2. JSON总结(java篇)
  3. Java中的构造函数和重载
  4. EXT4.2--Ext Designer 使用
  5. 如何用互联网上的广告来赚取广告费——有点吹牛吗?
  6. BZOJ2490 Zombie’s Treasure Chest
  7. hdu 5072 Coprime
  8. 无法添加选择的Web部件
  9. STM32 不断进入串口中断问题 解决方法
  10. Windows下配置单机Hadoop环境