汽车之家论坛字体反爬

当今社会基本每家每户都有车吧,基本都会去汽车之家查看车的详细参数(css反爬,下一篇文章会介绍),去汽车之家的论坛发表一些意见或看一下别人的意见啥的(字体反爬),那么我们今天就来看看汽车之家论坛的字体反爬又有什么稀奇古怪的呢(汽车之家是最早在网站使用字体反爬的)

  1. 确定要爬取的页面
    高速停车摘野果,六安高速交警迅速查处消隐患
    在这里插入图片描述
  2. 既然都确定是字体反爬了,那我们就直接找字体文件吧
    在这里插入图片描述
    在这里插入图片描述
  3. 按照正常思路就是把字体文件下载下来进行查看了
    在这里插入图片描述
    每次请求的字体文件里面的文字都是一样的,顺序不一样,和文字对应的name值也不一样,可以知道是动态字体
  4. 按照正常思路,就要分析同一个不同字体文件 有什么相同的地方了,但是对于这个网站不能这样了,算是一个bug吧(其实只是有点小毛病,后面会告诉你们)
    在这里插入图片描述
  5. 我们根据一个字体文件的on的值(我都是吧获取到的on值用md5加密一下)和文字做一个对应关系
    在这里插入图片描述
    然后每次请求的时候都用新的字体文件每个字的on值和自己构造的字典进行查找,再到网页中进行替换
  6. 这时候坑就来了,大部分字体都能替换 当某一个网页的加密数据里同时出现了, 上,十,三, 这三个字的时候,我现在这三个字都换成其中的一个字了 , 然后我就查看字形和加密后的数据,才发现这三个字的字形是一样的,别的文字都正常替换,我想了一会想了一个投机取巧的方法,就是把后面两个字的字形从后面删掉2个字符,4个字符在进行md5加密,这就不一样了(太机智了,哈哈哈)经过我的一番操作 成功替换了,我又换了几个网页测试,都能替换成功(这是邪魔外道,还是走正道吧)
  7. 接着研究字体文件,终于让我发现了
    在这里插入图片描述
    这样再做对应关系进行替换就可以了

代码如下(邪魔外道的就不放了,还是阳光正道好,哈哈哈)喜欢的同学来个一键三连哦

from hashlib import md5

from lxml import etree
import requests
import base64
import re
from fontTools.ttLib import TTFont

# url = 'https://club.autohome.com.cn/bbs/thread/fa46ecd8093668f7/96974096-1.html#pvareaid=6830286'
url = 'https://club.autohome.com.cn/bbs/thread/5a9162acffa561c0/96605902-1.html#pvareaid=6830286'
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"
}

ret = requests.get(url=url, headers=headers).text
# print(ret)
with open('qc.html', 'w', encoding='utf8') as f:
    f.write(ret)

with open('qc.html', 'r', encoding='utf8') as f:
    ret = f.read()
font_url = re.findall("format\('embedded-opentype'\),url\('(.*?)'\) format\('woff'\)", ret)[0]
cont = requests.get(url='http:' + font_url).content

with open('1.woff', 'wb') as f:
    f.write(cont)
font = TTFont('1.woff')
font.saveXML('1.xml')
uni_list = font.getGlyphOrder()[1:]

# 另一种方法 注释的地方
# font_cmap = [{'value': '更', 'hex': 'ce5dd2cee8e31242c555ddbf43af95e8'},
#              {'value': '右', 'hex': '0d31eff732a1d068a883b43637fb9c7e'},
#              {'value': '矮', 'hex': 'c6f0e96915c6654c0e12f6e2589ba199'},
#              {'value': '八', 'hex': 'f883b59e9d86f01130c76686a073d3c6'},
#              {'value': '好', 'hex': '688ed128e2845be5d1dfde0d3fc6079b'},
#              {'value': '左', 'hex': 'd3dbe3091adf1dc4571d1262fe2b7448'},
#              {'value': '得', 'hex': '26ced033253742cd921b7fcb9cd14e66'},
#              {'value': '的', 'hex': '94f6e353b637c0c1d7707e719232efe8'},
#              {'value': '了', 'hex': '0ba3636a9897da62f7593c2173641d89'},
#              {'value': '着', 'hex': '0b480f847a69b1853ed13b176ef4d797'},
#              {'value': '二', 'hex': '8afef86de3b0eff1ded7591aa5ff2769'},
#              {'value': '坏', 'hex': '6bd0bef6ce53dcc1937b6fba8e46177a'},
#              {'value': '一', 'hex': '3b5b9852567ef7618aac7f5f2d74ef74'},
#              {'value': '远', 'hex': '4bbb43dbb993745cf16f404a096464ce'},
#              {'value': '小', 'hex': 'cb1356023cb2b07b1accdf8cd12eedd6'},
#              {'value': '长', 'hex': '680b21efe94faa0cfdfc09043fc0227a'},
#              {'value': '七', 'hex': '0298cccd9b6bc80c6d49e94126877d9d'},
#              {'value': '是', 'hex': 'b5f5efe3baebf4bca885f8ca6f347e79'},
#              {'value': '少', 'hex': 'c2007ad197a98b81b7bf2805e85c744a'},
#              {'value': '低', 'hex': '9df7822580d45d40a49b4d8d33a185ca'},
#              {'value': '高', 'hex': 'dd8287475acb55d4f7e209b59c09e45e'},
#              {'value': '大', 'hex': 'a2e07c8e4a0fee0bc73cdec20c15c6da'},
#              {'value': '短', 'hex': '9683390ad884ba09df197cbfe82cc657'},
#              {'value': '五', 'hex': '1f2c4825991b6bd969174035a0cfec0a'},
#              {'value': '很', 'hex': '792a19499eb021ee330b6efe560061d8'},
#              {'value': '多', 'hex': 'c5d37acad757291244f30300c1870224'},
#              {'value': '九', 'hex': '1eab6ca768f7cdef8e847a299d5bb34f'},
#              {'value': '下', 'hex': 'fbbd62a1a58fa2aad6012de049e599f4'},
#              {'value': '呢', 'hex': 'e8ce47e581dd333e724e33d1a8830bb3'},
#              {'value': '六', 'hex': '20e490252446175c9b46c1aa1e338ab6'},
#              {'value': '上', 'hex': '3dcfec8e26ef48730f25363da55da77a'},
#              {'value': '和', 'hex': 'ee3210a2329256cfbb8688810f4dc6c4'},
#              {'value': '地', 'hex': 'ea08f5b720f9baae697ec67b9b3f6591'},
#              {'value': '不', 'hex': 'b3d1d22a1883593bad4d20697914c9f7'},
#              {'value': '近', 'hex': '8877e54e273d833af5288be3d2854317'},
#              {'value': '四', 'hex': '6f2ca97cc0b16de5432cd2d2c679a9a7'},
#              {'value': '三', 'hex': 'cf991820b977325adad84b8e332eb4b3'},
#              {'value': '十', 'hex': 'f9c3e6006fc9814d9415a26ac16e03b6'}]

page_html = etree.HTML(ret)
divs = page_html.xpath('//div[@class="tz-paragraph"]')[0]
texts = divs.xpath('.//text()')
print(texts)
tex = ''.join(texts).encode('utf8')

# k = {}
# count = -3
# for i,uni in enumerate(uni_list):
#     ev = eval("'\\u" + uni[3:] + "'").encode("utf-8")
#     font_on = font['glyf'].glyphs[uni].flags
#     md = md5(font_on).hexdigest()
#     if md not in k:
#         k[md]=uni
#     else:
#         font_on = font['glyf'].glyphs[uni].flags[:count]
#         md = md5(font_on).hexdigest()
#         k[md] = uni
#         count-=2
#
#
#     for u in font_cmap:
#         if md == u['hex']:
#             tex = tex.replace(ev,u['value'].encode('utf8'))
# print(tex.decode('utf8'))

'''
    if md not in k:
        print(uni, md)
        k[md]=uni
    else:
        font_on = font['glyf'].glyphs[uni].flags[:count]
        md = md5(font_on).hexdigest()
        print(uni, md)
        k[md] = uni
        count-=2
'''
with open('1.xml', 'r', encoding='utf8') as f:
    ans = f.read().replace('\n', '').replace(' ', '')
font_dict = {'2ee6282ddbee9f53de340fb93a156da1': '坏', '5de9503e9e8fb0b817c0e8046f68ea06': '少',
             'b85e1e0e4e0a3da21c7688d3734fbff4': '长', '7f6ffaa6bb0b408017b62254211691b5': '和',
             'd93d9c5cd0b124fe9a149e024230aedc': '三', 'a2044e0a05697a397d218ff3c7d58b14': '地',
             '284956d829845ea88648224b413ecfef': '得', '99b43a161e1b91fe521f4a956d0e461b': '呢',
             '96b244bd16f9e9b680668740b5f05f58': '是', '352a3fb74479f898abed255da7874f08': '八',
             '34145f477f06b62717bd3b9e550f2f59': '一', '8420d359404024567b5aefda1231af24': '右',
             '17bd84e98cb7dac55b8235e17f39e0c1': '好', '7bb21f3c5f26aa3004e7858c1708a171': '着',
             '84f04ce0e18cd521b3e4cc4d583c3804': '了', '70dc463ea84ed61832aad4be801dc590': '五',
             'cbe2b18c050de78223be644f1cbdf3e9': '大', '2dd8c79d2fa42c863c906142393b5672': '下',
             '739602f7c6011723ad000dc75a020d81': '近', '8602f737ddba61fa08d59db4a9ac304e': '十',
             '56b5240074776d63a3157985164e1347': '四', '2013ad23b3c0e210a3c06a6f0b32d7ff': '很',
             'fe306921fac2991ddeebc24f11083ccd': '左', 'f4e14bd8b0f0f4ac2b5b626868b46c0c': '矮',
             '0f1ed2182ab8a1d32ee53de13778dedb': '短', 'd1375517bb56ee0a6670ead7ee1b09fc': '九',
             'afac95ed683c255be0fb579dcc286a97': '远', 'cb35257195916c3eec46c5a8fd331d5d': '多',
             '618ad2ac1054473d4c77a483d65fee64': '低', '4f36bcfc60dc716bd3434d9c36762a27': '小',
             'e644a5af2b0b0834f14f1a0d2dfdd728': '七', 'b0169350cd35566c47ba83c6ec1d6f82': '六',
             'ca4de99bb59a97972fbc21b6d886e83a': '上', '70c480369c5a95ee190c178729322738': '不',
             '2421fcb1263b9530df88f7f002e78ea5': '高', 'd2b80d6d0aa059da6f71b58592c1c7b5': '的',
             '1d6f9e61e720fca9598bd3099739c37a': '更', 'e79c567ac2f3aa160297a5580ff96cbd': '二'}

k = {}
for i, uni in enumerate(uni_list):
    ev = eval("'\\u" + uni[3:] + "'").encode("utf-8")
    name, nub = re.findall(f'<TTGlyphname="({uni})"xMin=.*?valuespushed\*/(\d+)', ans)[0]
    md = md5(nub.encode('utf8')).hexdigest()
    tex = tex.replace(ev, font_dict[md].encode('utf8'))

print(tex.decode('utf8'))


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱笑的光头强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值