點評店鋪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裡面去擷取 電話和評論,遇到需要解析的就用 映射字典去 比對即可