最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python爬蟲實例之2021貓眼票房字體加密反爬策略(粗略版)

 更新時間:2021年02月22日 11:38:10   作者:綠色恐龍GT  
這篇文章主要介紹了Python爬蟲實例之2021貓眼票房字體加密反爬策略(粗略版),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言:

貓眼票房頁面的字體加密是動態(tài)的,每次或者每天加載頁面的字體文件都會有所變化,本篇內容針對這種加密方式進行分析

字體加密原理:簡單來說就是程序員在設計網(wǎng)站的時候使用了自己設計的字體代碼對關鍵字進行編碼,在瀏覽器加載的時會根據(jù)這個字體文件對這些字體進行編碼,從而顯示出正確的字體。

已知的使用了字體加密的一些網(wǎng)站:
58同城,起點,貓眼,大眾點評,啟信寶,天眼查,實習僧,汽車之家
本篇內容不過多解釋字體文件的映射關系,不了解的請自行查找其他資料。
如若還未入門爬蟲,請往這走 簡單粗暴入門法——Python爬蟲入門篇

import requests
import urllib.request as down
import json
from fontTools.ttLib import TTFont
import re
#分析用
import matplotlib.pyplot as plt #繪圖
import numpy as np # 科學計算庫

安裝:
pip install matplotlib
pip install requests
pip install numpy
pip install fonttools

首先我們對貓眼票房頁面進行簡單分析

分析

可以看到票房數(shù)字在審查中顯示的是亂碼,類似與這種情況的就可能是使用了字體加密,因此我們需要找到字體文件(字體文件會以鏈接方式存放在頁面中)

字體鏈接

找到了字體文件,下載并對映射關系進行分析,可以得到我們需要的一組基礎字形映射表;并且可以通過映射關系得到每個字形的所有坐標

baseFont=TTFont('maoyan.woff')
# 獲取相應數(shù)字的namecode和形狀坐標的關系,可用來獲取坐標
glyf=baseFont['glyf']
#通過對一份字體樣本分析得出的字體映射
baseNumberMaps={
 0:glyf['uniF632'],
 1:glyf['uniF2F1'],
 2:glyf['uniF0A4'],
 3:glyf['uniF7B7'],
 4:glyf['uniE82D'],
 5:glyf['uniF653'],
 6:glyf['uniE756'],
 7:glyf['uniF41A'],
 8:glyf['uniE79B'],
 9:glyf['uniE81E']
}
for num,name in baseNumberMaps.items():
 print(name.coordinates)

坐標

我們將坐標繪圖成圖形,在進行不同組字形圖形對比可以發(fā)現(xiàn)每套字形的坐標不同,大小比例不同,而字形是不變的,也就是相似

繪圖對比

對比坐標發(fā)現(xiàn)每套字形坐標都會有所改變,但是整體圖形還是同一個,所以我想到了斜率對比,我們計算每個字形部分線段的斜率,如果斜率之差小于一個數(shù)值,就說明這兩個是相同的數(shù)字。

在這里插入圖片描述

因此就得到了一個思路 獲得基礎字體映射關系表爬取頁面下載所加載的字體獲得需要對比的字體映射關系表計算每套字體每個字形的線段斜率,并進行差值計算循環(huán)匹配,從基礎字形的0-9開始去匹配新字形的斜率,如果斜率之差小于0.5并且樣本數(shù)>=9我們則認為兩個圖形為同一個數(shù)字,獲得正確的字體映射關系對加密字體進行替換得到正確內容

程序實現(xiàn)

import requests
import urllib.request as down
import json
from fontTools.ttLib import TTFont
import re
import MyPyClass

# 得到字體斜率列表(部分)
def font_Kdict(mapstype,maps=None):
 '''
 得到字體斜率字典(部分)
 參數(shù):
 mapstype:str->maps類型,判斷是是base/new
 maps:映射字典

 return kdict
 kdict字典關系:
 num:Klist 數(shù)字對應每條線段的斜率列表
 '''
 kdict={}
 # 遍歷maps字典,找到對應的num和namecode
 for num, namecode in maps.items():
 # 跳過無用數(shù)據(jù)
 if namecode == 'x': continue
 # 判斷類型,并從.coordinates得到對應num的所有坐標
 if mapstype=='base':coordinates = namecode.coordinates
 elif mapstype=='new':coordinates=glyf[namecode].coordinates
 # 得到坐標 X列表和坐標 Y列表
 x = [i[0] for i in coordinates]
 y = [i[1] for i in coordinates]
 Klist = []
 # 遍歷X列表并切片為前10個數(shù)據(jù)進行斜率計算,即代表繪圖的前10條線段的斜率
 for index, absx in enumerate(x[:10]):
  # 當斜率為0/1時,認為斜率為1計算
  if x[index + 1] == x[index] or y[index + 1] == y[index]:
  absxy = 1
  else:
  absxy = (y[index + 1] - y[index]) / (x[index + 1] - x[index])
  # 將斜率加入到列表
  Klist.append(-absxy if absxy < 0 else absxy)
 kdict[num]=Klist
 #print('base:', code, Klist, name)
 return kdict
# 對比斜率字典
def contrast_K(kbase,knew):
 '''
 對比斜率映射差距
 參數(shù):
 kbase:基礎字體映射表的斜率字典
 knew:當前鏈接的字體映射表的斜率字典

 return:dict
 fontMaps:根據(jù)對比得出正確的字體映射關系字典

 '''
 fontMaps = {}
 # 遍歷kbase字典
 for base in kbase.items():
 n = 0 # 成功匹配的斜率個數(shù)
 # 遍歷knew字典
 for new in knew.items():
  # 遍歷kbase>knew>下的兩組斜率,進行大小匹配,
  # 如果斜率k的差值小于0.5,并且樣本數(shù)>=9時,認為兩個坐標圖形相識只是大小比例不同
  # 即k<=0.5 n>=9
  for (k1,k2) in zip(base[1],new[1]):
  # k取正數(shù)
  k=k1-k2 if k1>k2 else k2-k1
  if k<=0.5:
   n+=1
   continue
  else:
   break
  if n>=9:
  # 匹配正確則添加進字典中 此時的字典關系是:code:num 代碼對應數(shù)字的關系
  fontMaps[str(hex(new[0]).replace('0x','&#x'))]=str(base[0])
  break
  n=0
 #print(fontMaps)
 return fontMaps

# 建立基礎字體對象
baseFont=TTFont('maoyan.woff')
# 獲取相應數(shù)字的namecode和形狀坐標的關系,可用來獲取坐標
glyf=baseFont['glyf']
#通過對一份字體樣本分析得出的字體映射
baseNumberMaps={
 0:glyf['uniF632'],
 1:glyf['uniF2F1'],
 2:glyf['uniF0A4'],
 3:glyf['uniF7B7'],
 4:glyf['uniE82D'],
 5:glyf['uniF653'],
 6:glyf['uniE756'],
 7:glyf['uniF41A'],
 8:glyf['uniE79B'],
 9:glyf['uniE81E']
}
url='https://piaofang.maoyan.com/dashboard-ajax?orderType=0&uuid=1778ad877f8c8-0b23bf32a2bb26-c7d6957-1fa400-1778ad877f8c8&riskLevel=71&optimusCode=10'
ua=MyPyClass.GetUserAgent()#獲得ua
# 爬取內容
with requests.get(url,headers={'user-agent':ua}) as response:
 # 獲取存放字典的json字段,并提取字體url
 fontStyle=json.loads(response.content)['fontStyle']
 fontStyle=re.findall('\"([\s\S]*?)\"',fontStyle[::-1])
 fonturl='http:'+fontStyle[0][::-1]# 字體url鏈接
 # 將加載的字體下載保存到本地,并對其進行分析
 down.urlretrieve(fonturl,'newfont.woff')
 # 爬取的電影數(shù)據(jù)內容
 content = json.loads(response.content)['movieList']['data']['list']
# 信息字典
movieNum={}#綜合票房數(shù)字典
movieDayOne= {}#上映首日數(shù)量
movieRate={}#票房占比
movieshowCount={}#排片場次
movieViewerAvg={}#場均人數(shù)
movieInfos={}
# 頁面內容
for i in content:
 moviename=i['movieInfo']['movieName']
 movieNum[moviename]=i['boxSplitUnit']['num']
 movieDayOne[moviename]=i['sumBoxDesc']
 movieRate[moviename]=i['splitBoxRate']
 movieshowCount[moviename]=i['showCount']
 movieViewerAvg[moviename]=i['avgShowView']

# 新字體對象
fontnew=TTFont('newfont.woff')
# 得到當前字體的映射關系表
newNumberMaps=fontnew.getBestCmap()
# 獲取字形
glyf=fontnew['glyf']
# 基礎字體斜率字典
k_base_dict=font_Kdict(maps=baseNumberMaps,mapstype='base')
# 新字體斜率字典
k_new_dict=font_Kdict(maps=fontnew.getBestCmap(),mapstype='new')
# 得到字體映射字典
fontcodes=contrast_K(k_base_dict,k_new_dict)
# 對加密的字體遍歷分組,并去除無用字符
for name,numbercode in movieNum.items():
 movieNum[name]=re.findall('([\S]*?);', numbercode)
# 根據(jù)得到的fontcodes映射對加密字體進行替換,得到正確數(shù)值
for index,(name,numbercodelist) in enumerate(movieNum.items()):
 num=[]
 # 替換操作
 for code in numbercodelist:
 if '.' in code:
  code=code.replace('.','')
  num.append('.'+fontcodes[code])
 else:
  num.append(fontcodes[code])
 infos=['排行:'+str(index+1),
 '片名',name,
 '上映首日',movieDayOne[name],
 '票房',''.join(num)+'萬',
 '票房占比',movieRate[name],
 '場均人數(shù)',movieViewerAvg[name]+'人',
 '排片場次',movieshowCount[name]]
 print(infos)

實現(xiàn)效果如下

效果

到此這篇關于Python爬蟲實例之2021貓眼票房字體加密反爬策略(粗略版)的文章就介紹到這了,更多相關Python爬蟲貓眼票房字體反爬內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Matplotlib繪圖基礎之幾何圖形的繪制詳解

    Matplotlib繪圖基礎之幾何圖形的繪制詳解

    除了繪制各類分析圖形(比如柱狀圖,折線圖,餅圖等等)以外,matplotlib?也可以在畫布上任意繪制各類幾何圖形,下面小編就來和大家講講如何繪制常見的幾種幾何圖形吧
    2023-08-08
  • python 序列類型list示例詳解

    python 序列類型list示例詳解

    列表(List)是一種有序的集合,可以包含任意類型的對象:數(shù)字、字符串甚至其他列表等,列表是可變的,這意味著我們可以添加、刪除或更改列表中的元素,這篇文章主要介紹了python 序列類型list示例詳解,需要的朋友可以參考下
    2024-04-04
  • python中reshape函數(shù)用法示例詳解

    python中reshape函數(shù)用法示例詳解

    reshape函數(shù)是Numpy庫中的一個函數(shù),可以用于改變一個數(shù)組的形狀,例如將一個二維數(shù)組轉換成一個三維數(shù)組,這篇文章主要介紹了python中reshape函數(shù)用法詳解,需要的朋友可以參考下
    2023-09-09
  • Python字符串格式化format()方法運用實例

    Python字符串格式化format()方法運用實例

    這篇文章主要給大家介紹了關于Python字符串格式化format()方法運用實例的相關資料,字符串格式化是Python編程中十分常用的部分,它可以幫助我們將更具可讀性的數(shù)據(jù)輸出到控制臺或寫入文件,需要的朋友可以參考下
    2023-08-08
  • Pytorch中關于BatchNorm2d的參數(shù)解釋

    Pytorch中關于BatchNorm2d的參數(shù)解釋

    這篇文章主要介紹了Pytorch中關于BatchNorm2d的參數(shù)解釋,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Python實現(xiàn)對照片中的人臉進行顏值預測

    Python實現(xiàn)對照片中的人臉進行顏值預測

    今天給大家?guī)淼氖顷P于Python實戰(zhàn)的相關知識,文章圍繞如何用Python實現(xiàn)對照片中的人臉進行顏值預測展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Python:合并兩個numpy矩陣的實現(xiàn)

    Python:合并兩個numpy矩陣的實現(xiàn)

    今天小編就為大家分享一篇Python:合并兩個numpy矩陣的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python列表生成式應用方式

    Python列表生成式應用方式

    這篇文章主要介紹了Python列表生成式應用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Python3遍歷目錄樹實現(xiàn)方法

    Python3遍歷目錄樹實現(xiàn)方法

    這篇文章主要介紹了Python3遍歷目錄樹實現(xiàn)方法,涉及Python目錄樹的遍歷操作技巧,需要的朋友可以參考下
    2015-05-05
  • python使用multiprocessing模塊實現(xiàn)帶回調函數(shù)的異步調用方法

    python使用multiprocessing模塊實現(xiàn)帶回調函數(shù)的異步調用方法

    這篇文章主要介紹了python使用multiprocessing模塊實現(xiàn)帶回調函數(shù)的異步調用方法,實例分析了multiprocessing模塊異步調用的相關使用技巧,需要的朋友可以參考下
    2015-04-04

最新評論

新晃| 逊克县| 定西市| 大新县| 甘孜| 乌审旗| 建宁县| 达尔| 屯昌县| 景德镇市| 项城市| 弋阳县| 花莲市| 修水县| 耿马| 贺州市| 东港市| 汉寿县| 方正县| 商南县| 南靖县| 五大连池市| 郯城县| 绥江县| 穆棱市| 丹阳市| 泰安市| 浏阳市| 白玉县| 琼结县| 繁昌县| 大埔县| 锦屏县| 高邑县| 朝阳区| 辽源市| 九台市| 诸暨市| 颍上县| 淳安县| 久治县|