转自https://jia666666.blog.youkuaiyun.com/article/details/109164340
练习平台
http://www.porters.vip/confusion/food.html
思路解析
一、SVG的具体表现
二、CSS文件
三、svg
四、举例详解
这里选择图一为例:
已知:
类名:vhkjj4
坐标:(-316px -141px)----取正整数则为(316,141)
可以自行选择其他类名进行尝试
源码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# SVG映射反爬虫 破解SVG加密的字符,得到正确的字符
# 测试网址:http://www.porters.vip/confusion/food.html
import re
import requests
class SVG_num():
def __init__(self, name):
self.class_name = name
self.main()
def main(self):
self.Get_file() # 获取css与svg文件
self.init_svg() # svg解析
self.svg_parse() # svg映射
def Get_file(self):
svg_link = "http://www.porters.vip/confusion/font/food.svg" # svg链接
css_link = "http://www.porters.vip/confusion/css/food.css" # css链接
# 获取svg与css文件内容
self.svg_text = requests.get(svg_link).text
css_text = requests.get(css_link).text
self.css_text = css_text.replace('\n', '').replace(' ', '') # 将换行符与空格清除,方便下一步匹配
# 定义一个函数用于匹配class属性为xx对应的css参数
def find_xy(self, in_text, class_value):
#.vhk9or {background:-330px-141px;}
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(self,in_text):
fs = re.compile(r'font-size:(\d+)px')
res = fs.findall(in_text)
return int(res[0])
def init_svg(self):
#<text x="14 28 42 56 70 84 98 112 126 140 154 168 182 196 210 224 238 252 266 280 294 308 322 336 350 364 378 392 406 420 434 448 462 476 490 504 518 532 546 560 574 588 602 616 630 644 658 672 686 700 714 728 742 756 770 784 798 812 826 840 854 868 882 896 910 924 938 952 966 980 994 1008 1022 1036 1050 1064 1078 1092 1106 1120 1134 1148 1162 1176 1190 1204 1218 1232 1246 1260 1274 1288 1302 1316 1330 1344 1358 1372 1386 1400 1414 1428 1442 1456 1470 1484 1498 1512 1526 1540 1554 1568 1582 1596 1610 1624 1638 1652 1666 1680 1694 1708 1722 1736 1750 1764 1778 1792 1806 1820 1834 1848 1862 1876 1890 1904 1918 1932 1946 1960 1974 1988 2002 2016 2030 2044 2058 2072 2086 2100 " y="38">154669136497975167479825383996313925720573</text>
#<text x="14 28 42 56 70 84 98 112 126 140 154 168 182 196 210 224 238 252 266 280 294 308 322 336 350 364 378 392 406 420 434 448 462 476 490 504 518 532 546 560 574 588 602 616 630 644 658 672 686 700 714 728 742 756 770 784 798 812 826 840 854 868 882 896 910 924 938 952 966 980 994 1008 1022 1036 1050 1064 1078 1092 1106 1120 1134 1148 1162 1176 1190 1204 1218 1232 1246 1260 1274 1288 1302 1316 1330 1344 1358 1372 1386 1400 1414 1428 1442 1456 1470 1484 1498 1512 1526 1540 1554 1568 1582 1596 1610 1624 1638 1652 1666 1680 1694 1708 1722 1736 1750 1764 1778 1792 1806 1820 1834 1848 1862 1876 1890 1904 1918 1932 1946 1960 1974 1988 2002 2016 2030 2044 2058 2072 2086 2100 " y="83">560862462805204755437571121437458524985017</text>
#<text x="14 28 42 56 70 84 98 112 126 140 154 168 182 196 210 224 238 252 266 280 294 308 322 336 350 364 378 392 406 420 434 448 462 476 490 504 518 532 546 560 574 588 602 616 630 644 658 672 686 700 714 728 742 756 770 784 798 812 826 840 854 868 882 896 910 924 938 952 966 980 994 1008 1022 1036 1050 1064 1078 1092 1106 1120 1134 1148 1162 1176 1190 1204 1218 1232 1246 1260 1274 1288 1302 1316 1330 1344 1358 1372 1386 1400 1414 1428 1442 1456 1470 1484 1498 1512 1526 1540 1554 1568 1582 1596 1610 1624 1638 1652 1666 1680 1694 1708 1722 1736 1750 1764 1778 1792 1806 1820 1834 1848 1862 1876 1890 1904 1918 1932 1946 1960 1974 1988 2002 2016 2030 2044 2058 2072 2086 2100 " y="120">671260781104096663000892328440489239185923</text>
#<text x="14 28 42 56 70 84 98 112 126 140 154 168 182 196 210 224 238 252 266 280 294 308 322 336 350 364 378 392 406 420 434 448 462 476 490 504 518 532 546 560 574 588 602 616 630 644 658 672 686 700 714 728 742 756 770 784 798 812 826 840 854 868 882 896 910 924 938 952 966 980 994 1008 1022 1036 1050 1064 1078 1092 1106 1120 1134 1148 1162 1176 1190 1204 1218 1232 1246 1260 1274 1288 1302 1316 1330 1344 1358 1372 1386 1400 1414 1428 1442 1456 1470 1484 1498 1512 1526 1540 1554 1568 1582 1596 1610 1624 1638 1652 1666 1680 1694 1708 1722 1736 1750 1764 1778 1792 1806 1820 1834 1848 1862 1876 1890 1904 1918 1932 1946 1960 1974 1988 2002 2016 2030 2044 2058 2072 2086 2100 " y="164">684431081139502796807382</text>
text = re.findall('y="(.*?)">(.*?)</text>', self.svg_text, re.S)
self.list_y = []
self.list_text = []
for i in range(len(text)):
self.list_y.append(text[i][0])
self.list_text.append(text[i][1])
def svg_parse(self):
x, y = self.find_xy(self.css_text, self.class_name) # 找出class=vhkjj4的xy坐标
real_y = [i for i in self.list_y if y <= i][-1] # 找出是哪一个 y [-1]是返方向
real_text = self.list_text[self.list_y.index(real_y)] # 找出是那个一 text
index = int(int(x) / 14) # 取整数下标
print('svg类名:' + self.class_name + '\n' +
'坐标:' + str((x, y)) + '\n' +
'字体大小:' + str(self.find_font_size(self.svg_text)) + '\n' +
'映射字符:' + str(real_text[index]))
if __name__ == '__main__':
name = 'vhkjj4'
example = SVG_num(name)
参考博客
作者:jspython
标题:5分钟看懂SVG反爬虫原理
https://blog.youkuaiyun.com/jspython/article/details/106071233
特别推荐没有svg基础的可以查看这个博客链接,我从中获益匪浅,有例子,有思路,有解析,源码与思路均来自于此,十分感谢原作者!!