“知物由學”是網易易盾打造的一個品牌欄目,詞語出自漢·王充《論衡·實知》。人,能力有高下之分,學習才知道事物的道理,而後才有智慧,不去求問就不會知道。“知物由學”希望透過一篇篇技術乾貨、趨勢解讀、人物思考和沉澱給你帶來收穫的同時,也希望開啟你的眼界,成就不一樣的你。當然,如果你有不錯的認知或分享,也歡迎在“網易易盾”公眾號後臺投稿。
隨著網際網路開放式、爆發式地增長,資料的價值變得越來越重要,尤其是電商、傳媒、社交等等業務,將資料比作黃金也不為過。因而隨之誕生了網路爬蟲技術,駭客透過呼叫網站開放的免費介面來批次獲取有價值的資料,用以資料探勘和分析行業狀況等。然而大量的非法爬蟲會造成網站伺服器壓力巨大,甚至影響正常使用者的訪問;而且有價值的資料被竊取,也會對網站的商業利益造成負面影響。
因此反爬蟲技術應運而生。反爬蟲技術大體包含“爬蟲識別”和“爬蟲反制”兩個步驟,後者主要是用於對前者識別出的爬蟲出的爬蟲進行懲罰和反制,主要包括限制訪問、驗證碼校驗、資料投毒等等,本文不做深究。而前者目前常用的方式是基於規則判斷。比如以某個使用者或者IP為單位,統計其在一定時間內的訪問記錄,然後用人為設定的一些閾值,這種可以稱為專家規則方法。其優點是規則明確、可靠,可以實時針對發現的爬蟲特徵來設定規則,從而實現與爬蟲對抗。
但是它也有明顯的缺點:
- 強依賴運營的經驗,規則和閾值難以憑空設定;
- 與爬蟲對抗依賴人為觀察爬蟲的特徵;
- 當規則越來越複雜且數量龐大時,規則引擎的效率會越來越低,成本會比較大。
由於上述原因,我們結合了兩項熱門的技術:大資料和機器學習,來探究其在爬蟲識別中的應用。
一、基於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等也類似,不再一一列出。
二、資料的特徵提取
要利用機器學習的演算法來實現爬蟲的判斷,首先要將原始資料轉化為向量,向量中的維度資料要儘量包含資料的特徵,這樣才能儘可能地區分爬蟲和正常記錄的差異。
透過觀察發現,爬蟲記錄與正常記錄相比,主要有以下特徵:
- 訪問總計數sum偏高;
- 每個URI的訪問計數較高;
- 訪問的URI比較集中,通常只訪問特定的幾個URI,而且可能呈現一定的比例;
- 訪問所用的User Agent比較單一;
- 每個User Agent的計數都很接近;
針對以上特徵,我們用以下維度來組成資料的特徵向量:
- 普通維度:這些維度是直接採用原始資料中的統計量,比如sum、URI.count、URI.max、URI.min、http_user_agent.count、http_user_agent.max、http_user_agent.min等等
- 方差維度:考慮到URI、http_user_agent等欄位的不同取值的分佈情況也是重要的特徵,把counts中value的方差也作為特徵維度
- 訂製維度:業務方對其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%。
對三段抽樣進行人工分析:
- 非爬蟲、爬蟲段:抽取少量資料,檢查是否有誤殺和漏殺;
- 嫌疑段:抽取大量資料來重點分析,判斷是否為爬蟲;
將分析完的資料作為新的訓練集,對原來訓練好的模型進行增量訓練,使模型在保留部分歷史經驗的情況下獲取新的特性。這一步當然也可以結合一些別的增量學習、遷移學習以及強化學習的演算法來實現。
點選免費體驗網易易盾安全解決方案。
相關閱讀:
知物由學第五十期 | 網易易盾深度學習模型工程化實踐
知物由學第四十九期 | 網易安全部總經理周森:內容安全遠比想象中的要複雜
知物由學第四十八期 | 對虛假影片的思考:當眼見也為虛,我們該怎麼辦?