点评店铺Svg字体加密(二)
网址 :http://www.dianping.com/shop/F4nE08K09Ptc47y4
在网页显示的时候是通过svg图片的内容,通过css的x和y的布局去映射的显示正确的文字
这个网页有不同的svg图片 进行映射,数字有数字的svg文件,文字有文字的svg文件,svg文件格式还是会变化的,有俩种格式
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL4VkeNhXVU5UNNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzYDNzUDN1kDM1AzMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
Svg的来源
找到svg文件,点击进入css文件,在css文件中可以找到3个svg文件,目前这个页面用到了俩个svg文件映射,一个电话一个是评论的
由于svg是动态的,我需要在css中动态的找出 svg的链接,css是首页HTML引用的,所以又需要在首页的HTML动态的获取css的链接
找到 css文件,打开搜索svg,你会发现有三个svg 的url,分别打开看看
svg 文件分析
可以打开3个svg打开看看,有三种格式,我们解析数据的时候就需要 三种解析的方式
第一种 :
可以 看到 x 和 y ,y 代表的是行数
class类名的 宽高属性,根据 x 去找 列,根据 y 去找行,就可以精准找到 哪个 字了
第二种 :
可以 看到 M0 24 H600 ,中间 24 是行数 ,textLength="364" 364/14 = 26 ,列数是 26,(第 24 行 第 26 个)
行数 和前面 还是一样,行数是没有一样,要找比 class类目的x属性 大的 下一行
第三种 :
拿简单的数字 做一个详细的案例
14 28 42 56 70 84 98 112 126 140 -->>> 对应 6928530714
.wlzfy { background: -106.0px -27.0px;} 这个 类名的 x 是 106 ,与上面的 比106 大的是 112,112 对应的是 7 ,所以wlzfy 显示的就是 数字 7
解析svg的代码
一般都是svg 转变 xml,然后在解析,我觉得更麻烦,直接用正则 更快的获取
def GetTwoSvgDict(SvgTwoUrl):
# SvgTwoUrl = 'http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/653d2e4bbc820c2a694c82fb4ce1cc6e.svg'
response = requests.get(SvgTwoUrl)
XYS = re.findall('<path id="(.*?)" d="M0 (.*?) H600"/>',response.text)
lenghtWordS = re.findall('<textPath xlink:href=".*?" target="_blank" rel="external nofollow" textLength="(.*?)">(.*?)</textPath>',response.text)
DictWords = {}
for XY,lenghtWord in zip(XYS,lenghtWordS):
DictWords[XY[1]] = list(lenghtWord[1])
# print(len(XYS),XYS)
# print(len(lenghtWordS),lenghtWordS)
# print(DictWords)
return DictWords
def GetOneSvgDict(SvgOneUrl):
# SvgOneUrl = 'http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/3fd533125709968774d6ab6900acf50c.svg'
response = requests.get(SvgOneUrl)
print(response.text)
lenghtWordS = re.findall('<text x="0" y="(.*?)">(.*?)</text>',response.text)
DictWords = {}
for lenghtWord in lenghtWordS:
DictWords[lenghtWord[0]] = list(lenghtWord[1])
# print(len(lenghtWordS),lenghtWordS)
# print(DictWords)
return DictWords
def GetNumSvgDict():
SvgThreeUrl ="http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/bd8a6e9b377242a155881bc468d4291c.svg"
response = requests.get(SvgThreeUrl, verify=False)
print(response.text)
XNumS = re.findall('<text x="(.*?)" y="41">(.*?)</text>',response.text)[0]
print(XNumS)
DictWords = {}
for val,key in zip(list(XNumS[1]),XNumS[0].strip().split(' ')):
DictWords[key] = [val]
# print(DictWords)
return DictWords
从 HTML 获取 css文件,从 css 获取 svg 链接
def GetSvgUrl(list_html):
"""获取woff字体的url"""
re_info = re.search(r'href="//s3plus(.*?)" target="_blank" rel="external nofollow" ', list_html)
if re_info:
SvgCSS_url = "http://s3plus" + re_info.group(1)
response = requests.get(SvgCSS_url, verify=False)
# 获取 处理的 SVG 对应的 值
SvgDictS = GetSvgDict(response.text)
# 获取 处理的 class 的值
ClassDictS = GetClassDict(response.text)
return SvgDictS, ClassDictS
这样就可以 获取 一个 动态的 svg 对应的,映射字典。
在从HTML里面去获取 电话和评论,遇到需要解析的就用 映射字典去 比对即可