国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

2021-11-25 22:19Python爬蟲與數據挖掘Python進階者 Python

字體反爬:一種常見的反爬技術,是網頁與前端字體文件配合完成的反爬策略,最早使用字體反爬技術的有58同城、汽車之家等等,現在很多主流的網站或APP也使用字體反爬技術為自身的網站或APP增加一種反爬措施。

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

今日網站

小編已加密:aHR0cHM6Ly93d3cuc2hpeGlzZW5nLmNvbS8= 出于安全原因,我們把網址通過base64編碼了,大家可以通過base64解碼把網址獲取下來。

字體反爬

字體反爬:一種常見的反爬技術,是網頁與前端字體文件配合完成的反爬策略,最早使用字體反爬技術的有58同城、汽車之家等等,現在很多主流的網站或APP也使用字體反爬技術為自身的網站或APP增加一種反爬措施。

字體反爬原理:通過自定義的字體來替換頁面中某些數據,當我們不使用正確的解碼方式就無法獲取正確的數據內容。

在HTML中通過@font-face來使用自定義字體,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

其語法格式為:

  1. @font-face{
  2.  
  3. font-family:"名字";
  4.  
  5. src:url('字體文件鏈接');
  6.  
  7. url('字體文件鏈接')format('文件類型')
  8.  
  9. }

字體文件一般是ttf類型、eot類型、woff類型,woff類型的文件運用比較廣泛,所以大家一般碰到的都是woff類型的文件。

以woff類型文件為例,其內容是怎樣的呢,又是以什么編碼方式使得數據與代碼一一對應的呢?

我們以某招聘網站的字體文件為例,進入百度字體編譯器并打開字體文件,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

隨機打開一個字體,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

可以發現字體6放在一個平面坐標里面,根據平面坐標的每個點來得出字體6的編碼,這里就不解釋如何得出字體6的編碼了。

如何解決字體反爬呢?

首先映射關系可以看作為字典,大致有兩種常用的方法:

第一種:手動把一組編碼和字符的對應關系提取出來并用字典的形式展示,代碼如下所示:

  1. replace_dict={
  2. '0xf7ce':'1',
  3. '0xf324':'2',
  4. '0xf23e':'3',
  5. .......
  6. '0xfe43':'n'
  7. }
  8. for key in replace_dict:
  9. 數據=數據.replace(key,replace_dict[key])

數據=數據.replace(key,replace_dict[key])

首先定義字體與其對應的代碼一一對應的字典,再通過for循環把數據一一替換。

注意:這種方法主要適用于字體映射少的數據。

第二種:首先下載網站的字體文件,再把字體文件轉換為XML文件,找到里面的字體映射關系的代碼,通過decode函數解碼,然后將解碼的代碼組合成一個字典,再根據字典內容將數據一一替換,由于代碼比較長,這里就不寫示例代碼了,待會在實戰演練中會展示這種方法的代碼。

好了,字體反爬就簡單講到這里,接下來我們正式爬取某招聘網站。

實戰演練

自定義字體文件查找

首先進入某招聘網并打開開發者模式,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

這里我們看到代碼中只有生字不能正常函數,而是用來代碼來替代,初步判定為使用了自定義的字體文件,這時就要找到字體文件了,那么字體文件在哪里找呢,首先打開開發者模式,并點擊Network選項,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

一般情況下,字體文件放在Font選卡中,我們發現這里一共有5個條目,那么哪個是自定義字體文件的條目呢,當我們每次點擊下一頁的時候,自定義字體文件就會執行一次,這時我們只需要點擊網頁中的下一頁即可,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

可以看到多了一個以file開頭的條目,這時可以初步判定該文件為自定義字體文件,現在我們把它下載下來,下載方式很簡單,只需要把file開頭的條目的URL復制并在網頁上打開即可,下載下來后在百度字體編譯器打開,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

這時發現打開不了,是不是找錯了字體文件,網站提示說不支持這種文件類型,那么我們把下載的文件后綴改為.woff在打開試試,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

這時就成功打開了。

字體映射關系

找到自定義字體文件了,那么我們該怎么利用呢?這時我們先自定義方法get_fontfile()來處理自定義字體文件,然后在通過兩步來把字體文件中的映射關系通過字典的方式展示出來。

字體文件下載與轉換;

字體映射關系解碼。

字體文件下載與轉換

首先自定義字體文件更新頻率是很高的,這時我們可以實時獲取網頁的自定義字體文件來防止利用了之前的自定義字體文件從而導致獲取數據不準確。首先觀察自定義字體文件的url鏈接:

  1. https://www.xxxxxx.com/interns/iconfonts/file?rand=0.2254193167485603
  2.  
  3. https://www.xxxxxx.com/interns/iconfonts/file?rand=0.4313944100724574
  4.  
  5. https://www.xxxxxx.com/interns/iconfonts/file?rand=0.3615862774301839

可以發現自定義字體文件的URL只有rand這個參數發生變化,而且是隨機的十六位小于1的浮點數,那么我們只需要構造rand參數即可,主要代碼如下所示:

  1. def get_fontfile():
  2. rand=round(random.uniform(0,1),17)
  3. url=f'https://www.xxxxxx.com/interns/iconfonts/file?rand={rand}'
  4. response=requests.get(url,headers=headers).content
  5. with open('file.woff','wb')as f:
  6. f.write(response)
  7. font = TTFont('file.woff')
  8. font.saveXML('file.xml')

首先通過random.uniform()方法來控制隨機數的大小,再通過round()方法控制隨機數的位數,這樣就可以得到rand的值,再通過.content把URL響應內容轉換為二進制并寫入file.woff文件中,在通過TTFont()方法獲取文件內容,通過saveXML方法把內容保存為xml文件。xml文件內容如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

字體解碼及展現

該字體.xml文件一共有4589行那么多,哪個部分才是字體映射關系的代碼部分呢?

首先我們看回在百度字體編碼器的內容,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

漢字人對應的代碼為f0e2,那么我們就在字體.xml文件中查詢人的代碼,如下圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

可以發現一共有4個結果,但仔細觀察每個結果都相同,這時我們可以根據它們代碼規律來獲取映射關系,再通過解碼來獲取對應的數據值,最后以字典的形式展示,主要代碼如下所示:

  1. with open('file.xml') as f:
  2. xml = f.read()
  3. keys = re.findall('', xml)
  4. values = re.findall('', xml)
  5. for i in range(len(values)):
  6. if len(values[i]) < 4:
  7. values[i] = ('\\u00' + values[i]).encode('utf-8').decode('unicode_escape')
  8. else:
  9. values[i] = ('\\u' + values[i]).encode('utf-8').decode('unicode_escape')
  10. word_dict = dict(zip(keys, values))

首先讀取file.xml文件內容,找出把代碼中的code、name的值并分別設置為keys鍵,values值,再通過for循環把values的值解碼為我們想要的數據,最后通過zip()方法合并為一個元組并通過dict()方法轉換為字典數據,運行結果如圖所示:

手把手教你 JS 逆向搞定字體反爬并獲取某招聘網站信息

獲取招聘數據

在上一步中,我們成功把字體映射關系轉換為字典數據了,接下來開始發出網絡請求來獲取數據,主要代碼如下所示:

  1. def get_data(dict,url):
  2. response=requests.get(url,headers=headers).text.replace('&#','0')
  3. for key in dict:
  4. response=response.replace(key,dict[key])
  5. XPATH=parsel.Selector(response)
  6. datas=XPATH.xpath('//*[@id="__layout"]/div/div[2]/div[2]/div[1]/div[1]/div[1]/div')
  7. for i in datas:
  8. data={
  9. 'workname':i.xpath('./div[1]/div[1]/p[1]/a/text()').extract_first(),
  10. 'link':i.xpath('./div[1]/div[1]/p[1]/a/@href').extract_first(),
  11. 'salary':i.xpath('./div[1]/div[1]/p[1]/span/text()').extract_first(),
  12. 'place':i.xpath('./div[1]/div[1]/p[2]/span[1]/text()').extract_first(),
  13. 'work_time':i.xpath('./div[1]/div[1]/p[2]/span[3]/text()').extract_first()+i.xpath('./div[1]/div[1]/p[2]/span[5]/text()').extract_first(),
  14. 'company_name':i.xpath('./div[1]/div[2]/p[1]/a/text()').extract_first(),
  15. 'Field_scale':i.xpath('./div[1]/div[2]/p[2]/span[1]/text()').extract_first()+i.xpath('./div[1]/div[2]/p[2]/span[3]/text()').extract_first(),
  16. 'advantage': ','.join(i.xpath('./div[2]/div[1]/span/text()').extract()),
  17. 'welfare':','.join(i.xpath('./div[2]/div[2]/span/text()').extract())
  18. }
  19. saving_data(list(data.values()))

首先自定義方法get_data()并接收字體映射關系的字典數據,再通過for循環將字典內容與數據一一替換,最后通過xpath()來提取我們想要的數據,最后把數據傳入我們自定義方法saving_data()中。

保存數據

數據已經獲取下來了,接下來將保存數據,主要代碼如下所示:

  1. def saving_data(data):
  2. db = pymysql.connect(host=host, user=user, password=passwd, port=port, db='recruit')
  3. cursor = db.cursor()
  4. sql = 'insert into recruit_data(work_name, link, salary, place, work_time,company_name,Field_scale,advantage,welfare) values(%s,%s,%s,%s,%s,%s,%s,%s,%s)'
  5. try:
  6. cursor.execute(sql,data)
  7. db.commit()
  8. except:
  9. db.rollback()
  10. db.close()

啟動程序

好了,程序已經寫得差不多了,接下來將編寫代碼運行程序,主要代碼如下所示:

  1. if __name__ == '__main__':
  2. create_db()
  3. get_fontfile()
  4. for i in range(1,3):
  5. url=f'https://www.xxxxxx.com/interns?page={i}&type=intern&salary=-0&city=%E5%85%A8%E5%9B%BD'
  6. get_data(get_dict(),url)

原文鏈接:https://mp.weixin.qq.com/s/nMDlvD6fiGwX3qTncmrVbw

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 婷婷91| 精品久久久久久久人人人人传媒 | 亚洲成人中文字幕 | 久久99精品久久久久久久 | 国产成人网 | 国产成人片| 日韩一区二区在线观看 | 国产成人精品一区二区三区视频 | 伊人五月天在线 | 欧美一级在线视频 | 2019中文字幕视频 | 成人h动漫精品一区二区器材 | 91国视频 | 99精品国产高清一区二区麻豆 | 亚洲视频一区二区三区 | 黄色一级在线观看 | 日韩欧美国产一区二区三区 | 欧美成年黄网站色视频 | www久久九| 国产在线a | 日韩中文字幕在线免费观看 | 久久久免费 | 日韩精品视频在线观看一区二区 | 欧美日韩综合视频 | www.99re| 国产中文字幕一区 | 色视频在线免费观看 | 精品成人av | 亚洲国产中文字幕 | 色综合天天天天做夜夜夜夜做 | 久草av在线播放 | www.国产| 精品在线看| 26uuu国产电影一区二区 | 国产精品99久久久久久www | 欧美亚洲综合久久 | 国产精品美女久久久久久久网站 | 亚洲欧美精品一区 | 国产日韩欧美视频 | 日韩视频专区 | 一区二区三区视频在线观看 |