<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          反爬篇 | 手把手教你處理 JS 逆向之字體反爬

          共 3649字,需瀏覽 8分鐘

           ·

          2022-05-24 12:08

          大家好,我是安果!

          上一篇文章我們講解了 JS 逆向中一種常見的反爬方案「 圖片偽裝 」

          反爬篇 | 手把手教你處理 JS 逆向之圖片偽裝

          本篇文章將聊聊另一種更加常見的反爬方案「 字體反爬

          它的實(shí)現(xiàn)原理為通過自定義的字體替換網(wǎng)頁元素中的部分內(nèi)容來實(shí)現(xiàn)的反爬策略

          常見的字體格式包含:ttf、eot、woff,我們一般在網(wǎng)頁中通過關(guān)鍵字「 @font-face 」定義字體樣式,然后再設(shè)置到元素控件樣式中去

          //定義字體樣式
          @font-face{
          ?font-family:"字體文件的名字,比如:gzfont";
          ?src:url('字體文件的鏈接');
          }

          //?給某個(gè)元素控件設(shè)置字體樣式
          .gzfont?{
          ????font-family:?gzfont;
          }

          目前有很多主流網(wǎng)站引入了字體反爬,比如:某 8 同城、某車之家等

          今天研究的目標(biāo)對(duì)象是:

          aHR0cHM6Ly93d3cuZ3VhemkuY29tL2J1eQ==

          1、分析一下

          打開目標(biāo)頁面及瀏覽器的開發(fā)者工具欄,我們發(fā)現(xiàn)汽車價(jià)格、首付金額、公里數(shù)中的部分內(nèi)容在源碼中顯示為亂碼,但在界面中展示正常

          元素的字體樣式名稱為「?gzfont

          我們?cè)诰W(wǎng)頁源碼中通過關(guān)鍵字「?gzfont 」嘗試查找字體的實(shí)際 URL 地址

          但是源碼中并未出現(xiàn)字體定義的邏輯,因此我們可以推測(cè)字體實(shí)際加載地址是通過 Ajax 加載的

          我們?cè)凇?Sources 」面板下,通過上面的關(guān)鍵字全局搜索該關(guān)鍵字出現(xiàn)的所有代碼塊進(jìn)行逐一分析

          通過新增一個(gè)斷點(diǎn),找到?gzfont 字段生成的邏輯及字體 URL 地址

          在瀏覽器的新窗口中,通過字體 URL 下載字體文件,然后在 PC 上使用軟件?FontCreator 打開查看

          下載地址:

          https://www.pcsoft.com.cn/soft/21156.html

          我們發(fā)現(xiàn)字體映射關(guān)系很簡(jiǎn)單,數(shù)目也很少,并且映射關(guān)系是固定的

          PS:每次重新加載頁面,字體 URL 地址、映射關(guān)系都是固定的

          所以,我們可以通過一個(gè)字典定義它們的映射關(guān)系

          #?字體映射關(guān)系
          # PS:由于字體數(shù)目很少,所以可以直接寫死字體的映射關(guān)系
          font_relation_map?=?{
          ????'uniE9CE':?0,
          ????'uniE41D':?1,
          ????'uniE630':?2,
          ????'uniEAF2':?3,
          ????'uniE325':?4,
          ????'uniE891':?5,
          ????'uniEC4C':?6,
          ????'uniE1D0':?7,
          ????'uniE76E':?8,
          ????'uniE52E':?9
          }

          最后,我們分析發(fā)現(xiàn)頁面數(shù)據(jù)都是通過下面的網(wǎng)絡(luò)請(qǐng)求獲取的

          我們只需要將里面的亂碼數(shù)據(jù)根據(jù)字體映射關(guān)系替換為正常的數(shù)據(jù)即可

          2、具體實(shí)現(xiàn)

          下面,我們聊聊爬取網(wǎng)頁內(nèi)容的步驟

          首先,我們需要安裝字體解析的依賴庫?fonttools

          #?安裝依賴
          pip3?install?fonttools

          然后,解析字體文件,根據(jù)上面響應(yīng)數(shù)據(jù)中的數(shù)據(jù)格式,重新組成一個(gè)新的字典數(shù)據(jù)

          def?get_font_map():
          ????"""
          ????獲取字體映射關(guān)系
          ????:return:
          ????"""

          ????font?=?TTFont(r'gzfont.woff2')

          ????#?字體文件轉(zhuǎn)為xml文件
          ????#?font.saveXML(r"font.xml")

          ????font_map?=?font.getBestCmap()
          ????font.close()

          ????#?print(font_map)

          ????new_font_map?=?{}

          ????#?遍歷字典,重新組成一個(gè)新的映射字典
          ????for?index,?key?in?enumerate(font_map):
          ????????value?=?font_map[key]

          ????????#?捕獲異常
          ????????try:
          ????????????temp?=?font_relation_map[value]
          ????????except:
          ????????????temp?=?''
          ????????if?temp?!=?'':
          ????????????#?根據(jù)響應(yīng)結(jié)果中字體反爬數(shù)據(jù)格式,將鍵值前面添加字符串&#,用于匹配
          ????????????new_font_map['&#'?+?str(key)?+?";"]?=?temp

          ????return?new_font_map

          接著,模擬上面的網(wǎng)絡(luò)請(qǐng)求獲取響應(yīng)數(shù)據(jù);遍歷上面的字典鍵值對(duì),判斷鍵?key 是否包含在響應(yīng)結(jié)果

          如果包含,就將響應(yīng)結(jié)果中的鍵 key 全部替換該鍵對(duì)應(yīng)的值 value

          import?json
          import?time
          import?requests

          def?get_car_list(pagenum:?int,?new_font_map:?dict):
          ????"""
          ????獲取車列表數(shù)據(jù)
          ????:param?new_font_map:
          ????:return:
          ????"""

          ????url?=?f"https://mapi.**.com/car-source/carList/pcList?osv=IOS&minor=&sourceType=&ec_buy_car_list_ab=**"

          ????payload?=?{}
          ????headers?=?{
          ????????'authority':?'mapi.**.com',
          ????????'accept':?'application/json,?text/plain,?*/*',
          ????????'origin':?'https://www.**.com',
          ????????'platform':?'5',
          ????????'referer':?'https://www.**.com/',
          ????????'token':?'',
          ????????'user-agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_15_7)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/101.0.4951.64?Safari/537.36'
          ????}

          ????resp_str?=?requests.request("GET",?url,?headers=headers,?data=payload).text

          ????#?全局替換
          ????for?key,?value?in?new_font_map.items():
          ????????if?key?in?resp_str:
          ????????????resp_str?=?resp_str.replace(key,?str(value))

          最后就可以進(jìn)行數(shù)據(jù)提取了

          ...
          #?數(shù)據(jù)解析
          ????resp?=?json.loads(resp_str)
          ????postList?=?resp.get("data").get("postList")

          ????for?item?in?postList:
          ????????title?=?item.get("title")
          ????????road_haul?=?item.get("road_haul")??#?公里
          ????????license_date?=?item.get("license_date")??#?購買時(shí)間
          ????????price?=?item.get("price")??#?價(jià)格
          ????????first_pay?=?item.get("first_pay")??#?首付

          ????????print(f'車型:{title},公里數(shù):{road_haul},購買時(shí)間:{license_date},價(jià)格:{price},首付:{first_pay}')
          ...

          運(yùn)行爬蟲,我們發(fā)現(xiàn)爬取到的數(shù)據(jù)不存在亂碼,都正常顯示了

          3、總結(jié)一下

          在日常工作中,應(yīng)對(duì)字體反爬的常規(guī)步驟如下:

          • 檢查網(wǎng)頁控件的字體名稱

          • 通過網(wǎng)頁源碼、Network 面板(Font)、Source 面板(關(guān)鍵字搜索)及調(diào)試的方式獲取字體地址

          • 在 PC 端通過軟件查看字體的映射關(guān)系

          • 通過頁面刷新、下載查看字體,判斷字體文件是否動(dòng)態(tài)生成

          • 使用依賴庫?fonttools 解析字體,根據(jù)元素內(nèi)容生成新的鍵值對(duì)

          • 對(duì)響應(yīng)結(jié)果根據(jù)鍵值對(duì)進(jìn)行內(nèi)容替換

          我已經(jīng)將文中所有源碼上傳到后臺(tái),回復(fù)關(guān)鍵字「 字體反爬 」即可以獲取完整源碼

          如果你覺得文章還不錯(cuò),請(qǐng)大家?點(diǎn)贊、分享、留言?下,因?yàn)檫@將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動(dòng)力!


          推薦閱讀


          用 Python 遠(yuǎn)程控制 Windows 服務(wù)器,太好用了!

          JavaScript 逆向爬蟲中的瀏覽器調(diào)試常見技巧

          JavaScript 逆向爬蟲中的瀏覽器調(diào)試常見技巧(下)

          反爬篇 | 手把手教你處理 JS 逆向之圖片偽裝


          END


          好文和朋友一起看~
          瀏覽 100
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  豆花视频无码 | 国产扒开腿精品无码高潮视频 | 麻豆视频免费观看 | 久久撸在线 | 欧美乱伦中文字幕 |