猫眼字体反爬
具体下来,这两个字体反爬都没有58同城的反爬那样繁琐。58同城反爬
具体解决思路:
1.获取对应加载的字体文件(可能是对网页上的base64加密字段进行解密,也能是去获得字体文件的url,以.ttf或.woff结尾的文件)
2.用1的步骤先下载好一个字体文件并用FontCreater进行查看,按照顺序写出对应字体
3.新请求下载一个字体文件并解析这个字体文件(注意这一次请求要与下面的解析网页保持同一个会话,不然字体文件对应的编码就不管用了)貌似每个文字是通过某种方式绘画出来的,所有同一个文字在不同的字体文件里面的参数是一样的,只不过对应的网页上的编码不一样而已,即对比前面下载好的字体文件的某个字体对应的参数去与新的字体文件的字体的参数进行匹配,匹配上了,就用对应的字体替换就好了。
先把下载好的第一个字体文件按照显示设置好映射
map_list = ['1','2','8','0','7','6','3','5','9','4']
后面用新的动态加载的字体文件的参数匹配前面的那个文件的字体的参数,并对应于这个列表。
在此之前
我们先测试一下,先下载两个字体文件并存储为xml格式
file_url = re.search("src:.*?,.*?url\('(.*?)'\) format\('woff'\);",response.text,re.S).group(1)
print(file_url)
with open('D:/maoyan_new1.woff','wb') as fp:
content = session.get('http:' + file_url, headers=headers).content
fp.write(content)
#上面那个先执行两次,修改一下文件名获取对应的xml文件进行比对字体参数
font = TTFont('D:/maoyan_base1.woff')
font.saveXML('D:/maoyan_base1.xml')
font_new = TTFont('D:/maoyan_new1.woff')
font_new.saveXML('D:/maoyan_new.xml')
下面对比一下字体的xml文件
可以看到只是name不一样
import requests
import re
from fontTools.ttLib import TTFont
url = 'https://maoyan.com/'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
}
session = requests.session()
response = session.get(url,headers=headers)
def get_woff_file():
file_url = re.search("src:.*?,.*?url\('(.*?)'\) format\('woff'\);",response.text,re.S).group(1)
print(file_url)
with open('D:/maoyan_new2.woff','wb') as fp:
content = session.get('http:' + file_url, headers=headers).content
fp.write(content)
def parse_font():
font = TTFont('D:/maoyan_base1.woff')
font.saveXML('D:/maoyan_base1.xml')
font_base_order = font.getGlyphOrder()[2:]
print(font_base_order)
# 根据第一次下载的文件写出对应
map_list = ['1','2','8','0','7','6','3','5','9','4']
font_new = TTFont('D:/maoyan_new2.woff')
font_new.saveXML('D:/maoyan_new2.xml')
font_new_order = font_new.getGlyphOrder()[2:]
print(font_new_order)
base_flag_list = list()
new_flag_list = list()
# 得到两个二维列表,对里面没个一维列表进行内容的比对,得到对应的字体
for i,j in zip(font_base_order,font_new_order):
flag_base = font['glyf'][i].flags
flag_new = font_new['glyf'][j].flags
base_flag_list.append(list(flag_base))
new_flag_list.append(list(flag_new))
memory_dict = dict()
for index1,x in enumerate(base_flag_list):
for index2,y in enumerate(new_flag_list):
if common(x,y):
key = font_new_order[index2]
key = '&#x' + key.replace('uni','').lower() + ';'
memory_dict[key] = map_list[index1]
print(memory_dict)
return memory_dict
def get_data(memory_dict):
all_data = re.findall('<span class="stonefont">(.*?)</span>万', response.text, re.S)
print(all_data)
for data in all_data:
for key,value in memory_dict.items():
data = data.replace(key,value)
print(data)# 只是做测试用就不提取那么多东西了
def common(list1,list2):
len1 = len(list1)
len2 = len(list2)
if len1 != len2:
return False
for i in range(len1):
if list1[i] != list2[i]:
return False
return True
if __name__ == '__main__':
get_woff_file()
memory_dict = parse_font()
get_data(memory_dict)
于是就可以获得结果了