相关文章推荐
从容的排球  ·  redis | 八、redis之Zset ...·  11 月前    · 
风流的开水瓶  ·  Rollup 与 Webpack 的 ...·  1 年前    · 
风流倜傥的佛珠  ·  Visual Studio Code ...·  1 年前    · 
pip install fontTools

或者到这个地址下载:https://files.pythonhosted.org/packages/81/d5/d6b345845163f6563c86748e82b9c6077e7ee21ab0289ad8a27a23985f6f/fonttools-3.39.0-py2.py3-none-any.whl

下载完之后,pip install fonttools-3.39.0-py2.py3-none-any.whl

1、目标网站

url = “https://su.58.com/qztech/”

2、反爬虫机制

网页上看见的
image
后台源代码里面的
image

从上面可以看出,生这个字变成了乱码,请大家特别注意箭头所指的数字。

1、确定反爬方法

在看了别人的解析文章之后,确定采取的是字体反爬机制,即网站定义了字体文件,然后进行相应的查找替换,在前端看起来,是没有任何差异的。其实从审查元素的也是可以看到的:

和大众点评的反爬差不多,都是通过css搞得。

2、寻找字体文件

以上面方框里的”customfont“为关键词搜了一下,发现就在源代码里面:

而且还有base64,直接进行解密,但是解密出来的其实是乱码,这个时候其实要做的很简单,把解密后的内容保存为.ttf格式即可。

  • ttf文件.ttf是字体文件格式。TTF(TrueTypeFont)是Apple公司和Microsoft公司共同推出的字体文件格式,随着windows的流行,已经变成最常用的一种字体文件表示方式。
  • @font-face是CSS3中的一个模块,主要是实现将自定义的Web字体嵌入到指定网页中去。

因为我们要对字体进行研究,所以必须将它打开,这里我是用的是FontCreator,打开以后是这个样子(其实很多字,在这里为了看的清楚,所以只截了下面的图):

很明显,每个字可以看到字形和字形编码。

观察现在箭头指的地方和前面箭头指的地方的数字是不是一样啊,没错,就是通过这种方法进行映射的。

所以我们现在的思路似乎就是在源代码里找到箭头指的数字,然后再来字体里找到后替换就行了。

恭喜你,如果你也是这么想的,那你就掉坑里了。

因为每次访问,字体字形是不变的,但字符的编码确是变化的。因此,我们需要根据每次访问,动态解析字体文件

字体1:
image
字体2:
image
所以想通过写死的方式也是行不通的。

这个时候我们就要对字体文件进行更深一步的研究了。

3、研究字体文件

刚刚的.ttf文件我们是看不到内部的东西的,所以这个时候我们要对字体文件进行转换格式,将其转换为xml格式,然后来查看:

具体操作如下:

from fontTools.ttLib import TTFont
font_1 = TTFont('58_font_1.ttf')
font_base.saveXML('font_1.xml')

xml的格式如下:

文件很长,我只截取了一部分。

仔细的观察一下,你会发现~这俩下面的x,y,on值都是一毛一样的。所以我们的思路就是以一个已知的字体文件为基本,然后将获取到的新的字体文件的每个文字对应的x,y,on值进行比较,如果相同,那么说明新的文字对就 可以在基础字体那里找到对应的文字,有点绕,下面举个小例子。

假设: “我” 在基本字体中的名为uni1,对应的x=1,y=1,n=1新的字体文件中,一个名为uni2对应的x,y, n分别于上面的相等,那么这个时候就可以确定uni2 对应的文字为”我”。

查资料的时候,发现在特殊情况下,有时候两个字体中的文字对应的x,y不相等,但是差距都是在某一个阈值之内,处理方法差不多,只不过上面是相等,这种情况下就是要比较一下。

其实,如果你用画图工具按照上面的x与y值把点给连起来,你会发现,就是汉字的字形~

所以,到此总结一下:

一、将某次请求获取到的字体文件保存到本地[基本字体];
二、用软件打开后,人工的找出每一个数字对应的编码[一定要保证顺序的正确,要不然会出事];
三、我们以后访问网页时,需要保存新字体文件;
四、用Fonttools库对基本字体与新字体进行处理,找到新的字体与基本字体之间的映射;
五、替换;

4、上代码

# coding=utf-8
import requests,base64,re,time
import  lxml.html as H
from fontTools.ttLib import TTFont
def get_data(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    session = requests.session()
    con = session.get(url, headers=headers)
    doc = H.document_fromstring(con.content)
    html=bytes.decode(con.content)
    font_data_origin = re.search(r'base64,(.*?)\)', html, re.S).group(1)
    font_data_after_decode = base64.b64decode(font_data_origin)
    new_font_name = "font_new.ttf"
    with open(new_font_name, 'wb') as f:
        f.write(font_data_after_decode)
    map_data = tff_parse(new_font_name)
    names = doc.xpath('//span[@class="infocardName fl stonefont resumeName"]/text()')
    # 有的时候会找不到,可以多执行几次;
    if names:
        for name in names:
            print('name in page source', name)
            for j in map_data.keys():
                    name = name.replace(j, map_data[j])
            print('name actual', name)
def tff_parse(font_parse_name):
    # 我这里的字体的顺序,如果你的不同,一定要修改
    font_dict = [u'博', u'经', u'硕', u'届', u'大', u'刘', u'8', u'1', u'士', u'E', u'2', u'6', u'张',
                 u'M', u'验', u'5', u'本', u'赵', u'陈', u'吴', u'李', u'生', u'4', u'校', u'以', u'应', u'黄',
                 u'技', u'无', u'女', u'A', u'周', u'中', u'3', u'王', u'7', u'0', u'9', u'科', u'高', u'男',
                 u'杨', u'专', u'下', u'B']
    font_base = TTFont('font_base.ttf')
    font_base_order = font_base.getGlyphOrder()[1:]
    # font_base.saveXML('font_base.xml')  调试用
    font_parse = TTFont(font_parse_name)
    # font_parse.saveXML('font_parse_2.xml')调试用
    font_parse_order = font_parse.getGlyphOrder()[1:]
    f_base_flag = []
    for i in font_base_order:
        flags = font_base['glyf'][i].flags
        f_base_flag.append(list(flags))
    f_flag = []
    for i in font_parse_order:
        flags = font_parse['glyf'][i].flags
        f_flag.append(list(flags))
    result_dict = {}
    for a, i in enumerate(f_base_flag):
        for b, j in enumerate(f_flag):
            if comp(i, j):
                key = font_parse_order[b].replace('uni', '')
                key = eval(r'u"\u' + str(key) + '"').lower()
                result_dict[key] = font_dict[a]
    return result_dict
def comp(L1, L2):
    if len(L1) != len(L2):
        return 0
    for i in range(len(L2)):
        if L1[i] == L2[i]:
        else:
            return 0
    return 1
if __name__ == '__main__':
    url = "https://su.58.com/qztech/"
    get_data(url)

github地址:https://github.com/xiaosimao/wx_code

看一下成果

字体解密相关资源

一是查看字体的软件 FontCreator,支持 window 。

链接:https://pan.baidu.com/s/1tUznnSB3siI2rVY9Whv88A 密码:ygz9

二是打开字体的网站,适合 mac 系统的朋友使用。

先通过 cloudconvert 把字体文件转化为 svg 后再用 fontello 打开查看

http://fontello.com/
https://cloudconvert.com/ttf-to-svg

如果嫌弃上面转换太过麻烦可以用百度字体打开。

http://fontstore.baidu.com/static/editor/index.html

推荐使用 FontCreator 以及百度字体。

打开后显示的样子与下图类似。
在这里插入图片描述

其实这个流程最大的问题就是我们人工录入的基本字体的字典数据有可能是会发生变化的,这就导致我们后面还要手动去改。

来源:https://cuiqingcai.com/6431.html
https://mp.weixin.qq.com/s/is1ScEk4cl5r8_uuEz5Jmw

目前已知的几个字体反爬的网站是猫眼,汽车之家,天眼查,起点中文网等等。本文用到的第三方库fontTools安装pip install fontTools或者到这个地址下载:https://files.pythonhosted.org/packages/81/d5/d6b345845163f6563c86748e82b9c6077e7ee21ab0289ad8a27a23985f6f...
一·字体反爬原理 🧾 🧾 Python字体反爬原理是指爬虫在爬取网站数据时,遇到了基于字体反爬的防护措施。这种反爬措施是通过将网站的文字转换成特定的字体文件,然后在页面上引用该字体文件来显示文字,使得爬虫无法直接获取文字内容。 🧾 具体原理如下: 网站将需要显示的文字转换成特定的字体文件,通常是TrueType或OpenType格式的字体文件。 网站在页面上引用该字体文件,并使用CSS样式将需要显示的文字的字体设置为该字体文件。 爬虫在获取页面源代码时,无法直接获取到需要显示的文字内容,只能获
题目链接:http://glidedsky.com/level/crawler-font-puzzle-1   我们首先看一下这道题与之前的题目有什么不同,前面的几道题不管用了哪种反爬手段,都是可以直接从源代码中提取数字的,但是这道题却不可以。将光标放到数字上,右键选择检查元素,可以看到数字的源码,源代码中显示的数字和我们在网页中看到的数字并不相同,且每次刷新页面时,网页上的数字不变,源代码中的数字会发生变化,因此本题的字体是动态映射的,无法通过事先构造映射表的方式来爬取。
爬虫遇到的问题 最近在用爬虫程序爬一些网站的时候发现爬到的数据出现乱码,不能正常显示: 如上图我们可以发现有些数据的数字变成了加密字体,我就去查看了一下网站的代码,结果发现网站的代码显示是这样的: 原来有些网站上使用了字体加密技术,为了解决这个问题,我找了大量的资料,可是网上的很多方法由于网站反爬技术的进步或者网站更新了字体加密规则已经不能使用了,于是我就开始了破解字体加密的艰辛历程。 解决方法...
2.爬取频率控制:适量控制爬取频率,使爬虫不会频繁地访问和抓取网站数据。 3.IP代理和User-Agent伪装:使用IP代理和User-Agent伪装,使得爬虫难以被检测和封锁。 4.验证码识别:应对特别严格的反爬虫措施,需要进行验证码识别。 5.数据去重:避免爬取重复数据,减少对网站负荷的压力。 6.合理的爬取深度:避免过深地爬取网站数据,减少风险。 总的来说,反反爬措施需要根据网站反爬虫的措施而定,通过模拟真实用户行为、IP代理伪装等手段提高爬虫抓取数据的成功率和新鲜度。