反爬蟲之字型反爬蟲
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參考
https://www.jianshu.com/p/4d28dd440cdd
相關文章
- C#爬蟲與反爬蟲--字型加密篇2019-06-26C#爬蟲加密
- 我去!爬蟲遇到字型反爬,哭了2021-06-07爬蟲
- Python爬蟲 - 記一次字型反爬2019-04-21Python爬蟲
- 爬蟲與反爬蟲技術簡介2022-09-20爬蟲
- 爬蟲與反爬:一場無休止之戰2022-07-21爬蟲
- 反爬蟲應對策略2023-12-01爬蟲
- Python爬蟲例項:爬取貓眼電影——破解字型反爬2019-02-26Python爬蟲
- 反爬蟲的應對措施2022-05-16爬蟲
- 代理IP如何突破反爬蟲?2021-09-11爬蟲
- 如何應對反爬蟲措施?2022-06-16爬蟲
- 對於反爬蟲偽裝瀏覽器進行爬蟲2018-04-12爬蟲瀏覽器
- 資料安全(反爬蟲)之「防重放」策略2020-03-05爬蟲
- 2個月精通Python爬蟲——3大爬蟲框架+6場實戰+反爬蟲技巧+分散式爬蟲2018-06-28Python爬蟲框架分散式
- 天天聊爬蟲,今天我們來聊聊反爬2018-12-19爬蟲
- 防止爬蟲被反爬的幾個主要策略2021-12-15爬蟲
- Web 端反爬蟲技術方案2019-03-04Web爬蟲
- 超輕量級反爬蟲方案2018-02-08爬蟲
- python爬蟲總是爬不到資料,你需要解決反爬蟲了2020-06-26Python爬蟲
- 反-反爬蟲:用幾行程式碼寫出和人類一樣的動態爬蟲2019-03-04爬蟲行程
- 「資料分析」2種常見的反爬蟲策略,資訊驗證和動態反爬蟲2022-02-23爬蟲
- 反 反爬蟲:用幾行程式碼寫出和人類一樣的動態爬蟲2017-12-19爬蟲行程
- 反爬蟲之檢測 PhantomJS 訪客2016-09-26爬蟲JS
- 反網路爬蟲以及解決方案2019-03-07爬蟲
- 常見的三種反爬蟲措施2022-05-31爬蟲
- 談談反爬蟲“政策與對策”2017-10-10爬蟲
- 【Python學習】爬蟲爬蟲爬蟲爬蟲~2018-05-03Python爬蟲
- 58同城 反爬蟲機制及處理2020-08-15爬蟲
- 普通反爬蟲機制的應對策略2017-04-26爬蟲
- 常見的反爬蟲和應對方法2016-01-24爬蟲
- 騰訊動漫爬蟲與動態隨機載入反爬2018-04-24爬蟲隨機
- 爬蟲app資訊抓取之apk反編譯抓取2019-05-10爬蟲APPAPK編譯
- 常見網站反爬蟲的解決措施2021-09-11網站爬蟲
- python爬蟲之反爬蟲(隨機user-agent,獲取代理ip,檢測代理ip可用性)2019-01-03Python爬蟲隨機
- Python爬蟲入門教程 61-100 寫個爬蟲碰到反爬了,動手破壞它!2019-04-22Python爬蟲
- 爬蟲:多程式爬蟲2021-05-19爬蟲
- [原創] 2018上半年網際網路惡意爬蟲分析:從全景視角看爬蟲與反爬蟲2020-02-05爬蟲
- 爬蟲之股票定向爬取2018-12-06爬蟲
- 知物由學 | 人工智慧時代,如何反爬蟲?2020-01-16人工智慧爬蟲