字體反爬之博X網實戰

今天的目標網站是某彩票網站博X網。其主要的反爬技術爲字體反爬,話不多說,我們直接開始!

我們想要獲取的是具體的開獎號碼,此號碼是通過藍色的小球表示的,如何獲取呢?

觀察NetWork後,我們很容易發現這些號碼數據等信息都以json的形式放在下圖紅色圈出的html頁面中。

而這些號碼數據是以類似於&#xff4e5這種形式表示的(上圖中藍色框部分)。

因此,我們的爬取路線可以分兩步走,先設法獲取該json數據,繼而通過某種方式將數據中的編碼轉換爲正常的數字。

JSON獲取

觀察該頁面的Headers數據,可知爲POST請求,其表單數據格式如下圖所示,

反覆刷新頁面發現code和limit是固定的參數,而path是不斷變化的,因而我們需要找到path參數才能夠構造POST請求訪問頁面並獲取數據。

我們複製當前的path參數到搜索框搜索,發現有兩個頁面包含該path參數。

txffc.html這個頁面正是我們爬取的目標頁面,我們只需要從該頁面的網頁源代碼中通過正則表達式獲取該path參數即可,也就是代碼中的woff_id。

從另外一個頁面,我們可以下載對應path的woff字體文件,並藉此解碼出這些數據,後面會詳細講。

得到path參數之後,我們可以輕鬆的構建POST請求,並獲取到相應的json數據,這裏建議選擇Headers參數的時候,除了User-Agent,記得將網頁請求攜帶的所有參數帶上,以防無法正常獲取數據。

字體反爬

上面講到,根據path我們已經可以獲取相應的woff文件,用FontCreator打開看看。

我們可以看到0-9一共十個數字,json數據中的&#xff4e5正是通過這樣的字體文件轉換的。

這裏出現了幾個難點。

  1. 字體文件實時變化,人工的方法只能每爬取一次,根據woff文件做一次轉換,來得到想要的數據;

  2. 不同時刻字體文件有些出入,比如上圖包含很多問號也就是無效的字符,而有些則不包含,比如下圖; 

  3. 這些字體對象的name和code不一致(與貓眼等網站不同),需要構建新的映射關係;

     

  4. 數字9的字體座標位置並不完全相同。 

這些問題自然是需要一個一個來解決。首先我們需要一個參照系,人工標識出字體的對應關係(base_dict),從而當新字體文件引入的時候,我們可以根據這個參照獲得新的映射關係。

base_dict={'glyph00009': 7, 'glyph00013': 2, 'glyph00018': 1, 'glyph00023': 6, 'glyph00028': 9, 'glyph00030': 8,'glyph00034': 4, 'glyph00039': 5, 'glyph00044': 3, 'glyph00048': 0}

通過get_new_name_list函數來篩選出有效的字體,上述的問號字體是不存在coordinates屬性的。 

由於該網站不同的字體文件數字9的座標位置有些許不同,這裏採用對比字體前十個座標來做判斷,如果完全相同,則認爲對應的字體是相同的數字。

我們由此可以得到新的字典new_dict——它的鍵爲新字體文件的字體對象的name,值爲字體對應的數字。

{'glyph00002': 6, 'glyph00003': 1, 'glyph00004': 0, 'glyph00005': 4, 'glyph00006': 7, 'glyph00007': 5, 'glyph00008': 8, 'glyph00009': 9, 'glyph00010': 3, 'glyph00011': 2}

接着爲了對應編碼與數字,我們需要重新建立新的字體映射表。通過getBestCmap函數,獲取對應字體的name與code之間的關係,由此我們可以得到映射表——鍵爲編碼,值爲數字,需要注意的是由於getBestCmap()會將內容轉化爲10進制,因此在後面存入字典的時候需要轉化爲16進制。

通過該映射表,我們可以輕鬆將獲取地json數據相關部分轉換爲可讀的數字。至此,我們就成功地解決了該網站的字體反爬。關於其他幾個經典的字體反爬網站,可以參考專輯裏面的文章~

——END——

推薦閱讀

圖像增強:灰度變換(Python實現)

解決滑動驗證碼的新姿勢

Python做一個藏頭詩生成器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章