反爬虫之字体反爬虫

栏目: 编程语言 · XML · 发布时间: 5年前

内容简介:细心的人会问,为什么不把所有的内容都替换成编码呢?这个就涉及到加载和渲染速度的问题。还有如果启动字体反爬虫,基本上已经告别SEO了,请仔细考虑中间的厉害关系,你懂得!我们知道,单纯汉字就有好几千个,还有各种字符,有的还包含各种外国人的字符串!如果全部放到自定义字体库中的话,这个文件灰常大,几十兆是肯定有的了,那后果啥样就很清楚了,加载肯定很慢,更糟糕的是如此之多的字体需要浏览器去渲染,那效果,卡到爆!!!为了解决这个问题,我们可以选择只渲染少量的、部分的文字,假设50个字,那么字体库就会小到几十K了,相当于

0x0 前言

反爬虫和爬虫之间的较量已经争斗多年,不管是攻还是守,已经持续N年,这是一个没有硝烟的战场,大家都知道爬虫和反爬之家的道高一尺魔高一丈的关系。但这个方案可以很大程度上可以增加普通爬虫的采集成本,在不使用OCR的前提下,算是比较极致的方案了。当然方案有很多种,层出不穷的各种方法,这里介绍的时候反爬虫的中的一种比较实用的方案,字体反爬也就是自定义字体反爬通过调用自定义的ttf文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容!必须通过程序去处理才能达到采集成本。

反爬虫之字体反爬虫

效果展示!

0x1 思路

细心的人会问,为什么不把所有的内容都替换成编码呢?这个就涉及到加载和渲染速度的问题。还有如果启动字体反爬虫,基本上已经告别SEO了,请仔细考虑中间的厉害关系,你懂得!

我们知道,单纯汉字就有好几千个,还有各种字符,有的还包含各种外国人的字符串!如果全部放到自定义字体库中的话,这个文件灰常大,几十兆是肯定有的了,那后果啥样就很清楚了,加载肯定很慢,更糟糕的是如此之多的字体需要浏览器去渲染,那效果,卡到爆!!!

为了解决这个问题,我们可以选择只渲染少量的、部分的文字,假设50个字,那么字体库就会小到几十K了,相当于一个小图片而已,加上CDN加速之类的,解决了。具体网络上又N种方法参考方法我会贴在下面!

如此简单?50个字儿呢可不是随便随便选择的,要选择那些爬虫采集不到就会很大改变整个语句的语义的词,直接点吧,也就是量词、否定词之类的。如原文“我有一头朱佩琪,我从来都不骑”,我们把其中的“一”、“不”放到我们的自定义字库中,这样一来,爬虫采集到的就是“我有头朱佩琪,我从来都骑”,嘿嘿,如果加上数字就更叼了,“漏洞版本 .. ???“ 是不是很猥琐。

但是上述方法早已让网络各位大神破解一遍了,这可如何是好呢?办法总是有的!如果让“叼”字的编码随机变化,但字体信息不变,浏览器渲染出来还是“叼”字那不就完美了,

于是,每个网页加载的时候,都随机加载了一套字体库,字体库的内容还是50个字,但每个字的顺序编码都是变化的,虽然我们打乱了关键字的编码顺序,但是每个字对应的字体信息是不变的,例如,“是”字一共有9划,每一笔划都有相应的x、y坐标信息,浏览器正是根据这些笔划信息渲染

反爬虫之字体反爬虫

如果吧,unicode编码和x,y坐标都骚做改动。他需要采集我的每一套字体库并且建立关系,这样增加的爬虫的成本,美滋滋。

0x3 实现

基于微软雅黑字库信息,抽取其中的关键字的字体信息,生成ttf 后 使用下方代码 开始随机然后随机生成上千套字库,后文章显示时随机从文件或者裤中查询出一套字库,并把文章中的关键字替换成Unicode编码进行渲染!

# encoding: utf-8
# -*-*-
# By:连长 『zh (www.lianzhang.org)』
# -*-*-
import random

from fontTools import ttx
from fontTools.ttLib import TTFont


def random_unicode(lengths):  # 随机生成Unicode字符集
    while True:
        shuma = ((str(random.sample(random_list, int(lengths))).replace('\'', '')).replace(',', '')). \
            replace(' ', '').replace('[', '').replace(']', '')
        if shuma[0].isalpha():
            return shuma
        else:
            continue


def TTFontsXML(filenames):  # 转换成XMl 到临时目录
    filenametemp = "temp/toolstemp.xml"
    font = TTFont(filenames)
    font.saveXML(filenametemp)
    return filenametemp


def TTFonts(filenames):  # 转换XML转换ttf
    try:
        print("开始转换字体!!!" + filenames)
        ttx.main([filenames])
        print ("-----------------------------------")
    except Exception as e:
        print ("Something went wrong converting ttx -> ttf/otf:")
        print (e)
        exit()


def Editfile(fontsjson, files):
    random_list = ["a", "v", "x", "s", "q", "w", "e", "r", "t", "y", "u", "i", "o", "z", "x", "c", "v", "b", "n", "m",
                   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ]
    shuma = ((str(random.sample(random_list, int(25))).replace('\'', '')).replace(',', '')). \
        replace(' ', '').replace('[', '').replace(']', '')
    filenametemp = "temp/" + shuma + ".xml"

    try:
        with open(files, 'r+') as fileOpen:
            data = fileOpen.read()
            fileOpen.close()

        for key in fontsjson.keys():
            data = data.replace(str(relationdic[key]), str(fontsjson[key]))
            data = data.replace(str(relationdic[key]).upper(), str(fontsjson[key]).upper())
        with open(filenametemp, 'w') as f:
            f.write(data)
            f.close()
        return shuma + ".ttf", filenametemp
    except Exception, ex:
        print ex
        filenametemp = "error"
        filenames = ""
        return filenametemp, filenames


if __name__ == '__main__':
    random_list = ['e', 'a', 'd', 'f', 'c', 'b', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    ttf_patn = "FontTest.ttf"  # 请输入ttf文件绝对路径:
    unicodelengths = 4  # 输入 UniCode 长度:
    ttfnumber = 10  # 输入生成多少个文件:
    relationdic = {"0": "e2f1", "1": "efab", "2": "eba3", "3": "eba5", "4": "edfd", "5": "c57f", "6": "e261",
                   "7": "f4d2", "8": "bad5", "9": "d4c2",
                   "A": "bfec5", "B": "fc736", "C": "e6d21", "D": "be4a9", "E": "c0e8f", "F": "d3c26", "G": "b18a0",
                   "H": "acb06", "I": "fd33e", "J": "fd36e", "K": "d417c", "L": "ad31e", "M": "ec95a", "N": "b39ce",
                   "O": "d508a", "P": "a961d", "Q": "a76b0", "R": "b7f12", "S": "b0426", "T": "d5941", "U": "ede47",
                   "V": "fc5a6", "W": "ed947", "X": "fd781", "Y": "b761a",
                   "Z": "af370", "a": "fde89", "b": "ecb21", "c": "c123c", "d": "b4c2c", "e": "cbbc7", "f": "c10cb",
                   "g": "cb78b", "h": "fdac7", "i": "076fe", "j": "d0def", "k": "ed6de", "l": "eaa1a", "m": "de1e9",
                   "n": "9eaa5", "o": "123e5", "p": "e12e2", "q": "e5efd", "r": "e6ea9", "s": "e1e8a", "t": "b8eac",
                   "u": "23e1c", "v": "ea6ac",
                   "w": "b87de", "x": "e5dac", "y": "2ccea",
                   "z": "3ada9"}  # 必须当前混淆ttf填入关系 否则不知道谁是谁了。。。生成的json 文件也是错误的。。
    try:

        macs = len(relationdic) + 50 * ttfnumber  # 可能会有重复 多加点
        tem_list = []
        for x in range(0, int(macs)):
            tem_list.append(random_unicode(unicodelengths))
        tem_list = list(set(tem_list))  # 去重

        tempfontsxmlpa = TTFontsXML(ttf_patn)  # 转换到临时XML地址。。

        okjson = []

        for f in range(0, ttfnumber):
            relationdictemp = relationdic.copy()
            for key in relationdictemp.keys():
                b = random.sample(tem_list, 1)
                tem_list.remove(b[0])
                relationdictemp[key] = b[0]
            filenames, filenametemp = Editfile(relationdictemp, tempfontsxmlpa)
            if filenametemp != "error":  # 如果返回修改成功 启动转换ttf的程序!
                TTFonts(filenametemp)
                jsonSeve = {"url": filenames, "data": relationdictemp}
                okjson.append(jsonSeve)
            


    except Exception, ex:
        print ex

反爬虫之字体反爬虫 Git: https://github.com/hackxx/AntiCrawlerFontGeneration

上述代码中 不带x,y混淆,请自己修改代码谢谢,如有需要请联系我!

0x4 参考


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code Reading

Code Reading

Diomidis Spinellis / Addison-Wesley Professional / 2003-06-06 / USD 64.99

This book is a unique and essential reference that focuses upon the reading and comprehension of existing software code. While code reading is an important task faced by the vast majority of students,......一起来看看 《Code Reading》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具