人工智能時代,如何反爬蟲?

​​“知物由學”是網易易盾打造的一個品牌欄目,詞語出自漢·王充《論衡·實知》。人,能力有高下之分,學習才知道事物的道理,而後才有智慧,不去求問就不會知道。“知物由學”希望通過一篇篇技術乾貨、趨勢解讀、人物思考和沉澱給你帶來收穫的同時,也希望打開你的眼界,成就不一樣的你。當然,如果你有不錯的認知或分享,也歡迎在“網易易盾”公眾號後臺投稿。





隨著互聯網開放式、爆發式地增長,數據的價值變得越來越重要,尤其是電商、傳媒、社交等等業務,將數據比作黃金也不為過。因而隨之誕生了網絡爬蟲技術,黑客通過調用網站開放的免費接口來批量獲取有價值的數據,用以數據挖掘和分析行業狀況等。然而大量的非法爬蟲會造成網站服務器壓力巨大,甚至影響正常用戶的訪問;而且有價值的數據被竊取,也會對網站的商業利益造成負面影響。


因此反爬蟲技術應運而生。反爬蟲技術大體包含“爬蟲識別”和“爬蟲反制”兩個步驟,後者主要是用於對前者識別出的爬蟲出的爬蟲進行懲罰和反制,主要包括限制訪問、驗證碼校驗、數據投毒等等,本文不做深究。而前者目前常用的方式是基於規則判斷。比如以某個用戶或者IP為單位,統計其在一定時間內的訪問記錄,然後用人為設定的一些閾值,這種可以稱為專家規則方法。其優點是規則明確、可靠,可以實時針對發現的爬蟲特徵來設定規則,從而實現與爬蟲對抗。


但是它也有明顯的缺點:

  1. 強依賴運營的經驗,規則和閾值難以憑空設定;
  2. 與爬蟲對抗依賴人為觀察爬蟲的特徵;
  3. 當規則越來越複雜且數量龐大時,規則引擎的效率會越來越低,成本會比較大。

由於上述原因,我們結合了兩項熱門的技術:大數據和機器學習,來探究其在爬蟲識別中的應用。


一、基於Flink的大數據統計


首先我們需要通過一些大數據技術來獲取統計數據。Flink是一個新興的分佈式大數據流處理引擎,本文不做詳細介紹,只是利用了其基於事件時間窗口統計數據的功能。
流處理過程主要包含以下步驟:


知物由學 | 人工智能時代,如何反爬蟲?

Flink流處理過程

  • 數據源:我們的數據源是業務網站吐出的Nginx訪問日誌,保存在kafka隊列中。
  • 預處理:按照數據源中的數據格式,將訪問日誌中有用的字段解析出來,主要是Timestamp、IP、URI、Htpp_User_Agent等。
  • 維度聚合:利用Flink的keyby功能,將同一IP的數據彙總起來。
  • 時間窗口:利用Flink的Window功能,把Timestamp處於某一時間窗口內的數據彙總到一起。我們採用的是滑動窗口的方式,統計15分鐘之內的數據,每1分鐘滑動一次。
  • 統計:通過以上兩步,我們每1分鐘結束,都能獲得每個IP在前15分鐘內的所有訪問記錄。我們對這些數據進行進一步統計,得到的數據以Json形式寫入到Kafka,格式如下圖


知物由學 | 人工智能時代,如何反爬蟲?

Flink輸出數據

字段含義:

  • Timestamp:窗口結束時間的時間戳;
  • IP:該數據所屬的IP;
  • Sum:該IP在時間區間內的總訪問次數
  • URI:該IP在時間區間內訪問的URI的具體統計

a)counts: 是一個map,key是所訪問的URI,value是訪問計數

b)count: counts中不同key的數量

c)sum: counts中所有value的和

d)min: counts中所有value的最小值

e)max: counts中所有value的最大值

  • Http_User_Agent:該IP在時間區間內訪問記錄所使用的User Agent的具體統計。內部的counts、count、sum、min、max與URI中的類似
  • 其他還有一些字段如http_referer、status、params、http_version等也類似,不再一一列出。


二、數據的特徵提取


要利用機器學習的算法來實現爬蟲的判斷,首先要將原始數據轉化為向量,向量中的維度數據要儘量包含數據的特徵,這樣才能儘可能地區分爬蟲和正常記錄的差異。


通過觀察發現,爬蟲記錄與正常記錄相比,主要有以下特徵:

  1. 訪問總計數sum偏高;
  2. 每個URI的訪問計數較高;
  3. 訪問的URI比較集中,通常只訪問特定的幾個URI,而且可能呈現一定的比例;
  4. 訪問所用的User Agent比較單一;
  5. 每個User Agent的計數都很接近;


針對以上特徵,我們用以下維度來組成數據的特徵向量:

  1. 普通維度:這些維度是直接採用原始數據中的統計量,比如sum、URI.count、URI.max、URI.min、http_user_agent.count、http_user_agent.max、http_user_agent.min等等
  2. 方差維度:考慮到URI、http_user_agent等字段的不同取值的分佈情況也是重要的特徵,把counts中value的方差也作為特徵維度
  3. 訂製維度:業務方對其URI分佈有一定的瞭解,可以對URI.counts中的數據做一個二次統計,產生一些訂製維度。比如把key匹配正則表達式“^/api/v\\\\d+/products/.*”的記錄的value相加,來作為一個新的特徵維度。同樣的也可用http_user_agent.counts中的數據產生訂製維度


三、線下分析


我們採用神經網絡算法,該算法的優點是: 技術成熟、適應性強、工程化容易、可移植性強等等。但是它是一種有監督學習,需要有一批訓練數據才能工作。


3.1 訓練數據獲取階段:


獲取訓練數據的思路有兩種:

  • 3.1.1 藉助規則引擎法:我們已經擁有一個規則引擎,可以用它配置一些簡單的規則,然後把規則引擎判斷出的結果作為標記,和原始數據一起作為訓練集數據。這種方法的優點是簡單、直觀;且規則越複雜,則相應訓練出來的模型也越優秀,區分爬蟲的能力越強。但是缺點也是很明顯的,因為依賴了規則引擎,所以也繼承了規則引擎的弊端,要創建合適的規則比較困難,而且學習後的模型也只是能起到和規則引擎一樣的效果,無法識別更多特殊的異常。所以該方法必須要搭配數據反饋和模型進化,才能使模型更加智能。


  • 3.1.2 人工標記法:這也是一種常見的獲取訓練集的方式,訓練集越完備,數據代表性越好則訓練出來的模型越優秀。但是該種方法最大的缺點是工作量巨大,面對海量的大數據,我們不可能做到一一標記,因此這種方法的難點就在於如何高效地獲取有效數據。


我們採用的方法是基於PCA+Kmeans的無監督學習算法,大概步驟如下:


  • 先採樣一批提取完特徵的數據作為輸入
  • 對原始的特徵數據做PCA主成分分析,通過線性變換獲得方差最大的幾個主成分維度,作為新的、降維後的特徵向量,這一步是為了提取特徵向量中的有效成分,去除無用信息
  • 對降維後的數據採用Kmeans算法進行聚類,得到若干個類別,並且對每條數據標記類別號
  • 對於每類數據,抽取最有代表性的若干條數據,人為分析對應的原始數據,判斷是否為爬蟲,然後計算抽取數據中爬蟲的比例。如果比例超過一定閾值,則將該類標記為爬蟲;如果比例小於一定閾值,則將該類標記為正常;比例在上下閾值之間的做對類內數據做進一步聚類,再做類似的判斷
  • 用類別的標記來標記類內的每條數據,得到了帶標記的訓練數據集
  • 這種方式需要在效果和工作量之間做取捨。當然也可以搭配數據反饋和模型進化,使模型表現更好。


3.2 模型構建和訓練階段


使用Pytorch搭建神經網絡模型。可以分批、多組地用同一批數據反覆訓練模型。 當達到一定的迭代次數,或者損失函數小於一定閾值,則表示模型訓練完畢。可以將模型參數文件導出,供線上部署。


知物由學 | 人工智能時代,如何反爬蟲?

一個簡單的單層神經網絡例子

知物由學 | 人工智能時代,如何反爬蟲?

知物由學 | 人工智能時代,如何反爬蟲?

訓練過程

知物由學 | 人工智能時代,如何反爬蟲?

在測試集上的測試結果


四、線上部署


模型引擎的線上部署如下圖所示。Training模塊負責數據的線下處理和訓練,訓練完的模型文件上傳至Nos,然後將模型的配置信息以及模型文件的地址寫入Etcd。Model Engine模塊是線上的模型引擎,實時監聽Etcd中額配置,當配置更新時,會立即拉取模型文件,並加載。


Model Engine會消費Flink統計完寫入Kafka的數據,並用模型做爬蟲判別,並將判別的結果寫入數據庫,供其他系統查詢使用。


知物由學 | 人工智能時代,如何反爬蟲?

線上部署架構


五、模型進化


到此我們已經搭建了包含數據採集、線下訓練、線上部署的模型引擎架構,但是正如前面所說,目前的模型只能達到與規則引擎相近的效果,要想讓模型進化得更為智能,必須加入反饋機制,使得模型能夠進化。


反饋的思路是從模型引擎的輸出數據入手。神經網絡分類算法的輸出數據,除了包含記錄是否屬於爬蟲的判斷,還包含是否屬於爬蟲的概率。可以根據概率分為三段:非爬蟲:0~33%、疑似爬蟲:33%~66%,爬蟲:66%~100%。


對三段抽樣進行人工分析:

  • 非爬蟲、爬蟲段:抽取少量數據,檢查是否有誤殺和漏殺;
  • 嫌疑段:抽取大量數據來重點分析,判斷是否為爬蟲;


將分析完的數據作為新的訓練集,對原來訓練好的模型進行增量訓練,使模型在保留部分歷史經驗的情況下獲取新的特性。這一步當然也可以結合一些別的增量學習、遷移學習以及強化學習的算法來實現。



分享到:


相關文章: