成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發 前端
aHR0cHM6Ly93d3cuc2hpeGlzZW5nLmNvbS8= 出于安全原因,我們把網址通過base64編碼了,大家可以通過base64解碼把網址獲取下來。

[[436608]]

今日網站

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

字體反爬

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

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

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

其語法格式為:

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

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

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

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

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

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

如何解決字體反爬呢?

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

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

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

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

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

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

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

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

實戰演練

自定義字體文件查找

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

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

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

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

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

這時就成功打開了。

字體映射關系

找到自定義字體文件了,那么我們該怎么利用呢?這時我們先自定義方法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文件內容如下圖所示:

字體解碼及展現

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

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

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

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

  1. with open('file.xml'as f: 
  2.     xml = f.read() 
  3. keys = re.findall('<map code="(0x.*?)" name="uni.*?"/>', xml) 
  4. values = re.findall('<map code="0x.*?" name="uni(.*?)"/>', 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()方法轉換為字典數據,運行結果如圖所示:

獲取招聘數據

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

  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=userpassword=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) 

 

責任編輯:武曉燕 來源: Python爬蟲與數據挖掘
相關推薦

2022-05-26 12:26:27

CSSJS逆向

2022-04-06 09:02:58

JS反編譯App

2020-07-10 08:24:18

Python開發工具

2018-03-23 20:45:23

機器學習NLP文本數據

2020-12-08 10:32:15

Python郵件tcp

2022-01-04 08:52:14

博客網站Linux 系統開源

2021-05-08 08:04:05

Python爬取素材

2021-05-10 06:48:11

Python騰訊招聘

2011-01-10 14:41:26

2011-05-03 15:59:00

黑盒打印機

2025-05-07 00:31:30

2022-02-23 20:53:54

數據清洗模型

2021-07-14 09:00:00

JavaFX開發應用

2020-03-08 22:06:16

Python數據IP

2021-07-03 09:04:22

XPathPython免費代理IP

2020-08-12 09:07:53

Python開發爬蟲

2020-12-07 09:01:58

冪等系統f(f(x)) =f(

2011-02-22 13:46:27

微軟SQL.NET

2021-02-26 11:54:38

MyBatis 插件接口

2021-12-28 08:38:26

Linux 中斷喚醒系統Linux 系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91亚洲精华国产 | 精品日韩一区 | 国产欧美日韩在线 | 在线一区视频 | 亚洲一区日韩 | 免费在线观看黄色av | 中文字幕日韩欧美 | 欧美极品在线观看 | 日韩av免费在线电影 | 久久久av| 激情一区二区三区 | 亚洲视频一区在线播放 | 成人国产精品色哟哟 | 中文字幕一区在线观看视频 | 欧美日韩国产在线观看 | 国产精品波多野结衣 | 欧美黄色一区 | 免费在线观看一区二区 | 一区二区精品在线 | 一区二区电影网 | 国产一级片 | 中文字幕久久精品 | 亚洲一区中文字幕在线观看 | av在线一区二区三区 | 免费在线精品视频 | 色综合视频 | 欧美亚洲国产一区二区三区 | 久久综合久色欧美综合狠狠 | 亚洲人在线观看视频 | 国产精品高 | 国产综合精品一区二区三区 | 精精国产xxxx视频在线播放7 | 国产91久久久久蜜臀青青天草二 | 国产精品福利在线观看 | 在线中文av| 久久av资源网 | 欧美在线一区二区视频 | 精品综合 | 精品国产伦一区二区三区观看方式 | 日韩av在线一区二区 | 欧美性猛交一区二区三区精品 |