摘要:之前在學校曾經(jīng)用過的方法做過一些爬蟲腳本來玩,從正式轉(zhuǎn)前端之后,出于興趣,我對爬蟲和反爬蟲又做了一些了解,并且做了一些爬蟲攻防的實踐。爬蟲腳本通常會很頻繁的進行網(wǎng)絡請求,比如要爬取豆瓣排行榜的電影,就會連續(xù)發(fā)送個網(wǎng)絡請求。
之前在學校曾經(jīng)用過request+xpath的方法做過一些爬蟲腳本來玩,從ios正式轉(zhuǎn)前端之后,出于興趣,我對爬蟲和反爬蟲又做了一些了解,并且做了一些爬蟲攻防的實踐。
我們在爬取網(wǎng)站的時候,都會遵守 robots 協(xié)議,在爬取數(shù)據(jù)的過程中,盡量不對服務器造成壓力。但并不是所有人都這樣,網(wǎng)絡上仍然會有大量的惡意爬蟲。對于網(wǎng)絡維護者來說,爬蟲的肆意橫行不僅給服務器造成極大的壓力,還意味著自己的網(wǎng)站資料泄露,甚至是自己刻意隱藏在網(wǎng)站的隱私的內(nèi)容也會泄露,這也就是反爬蟲技術(shù)存在的意義。
下面開始我的攻防實踐。
先從最基本的requests開始。requests是一常用的http請求庫,它使用python語言編寫,可以方便地發(fā)送http請求,以及方便地處理響應結(jié)果。這是一段抓取豆瓣電影內(nèi)容的代碼。
import requests from lxml import etree url = "https://movie.douban.com/subject/1292052/" data = requests.get(url).text s=etree.HTML(data) film=s.xpath("http://*[@id="content"]/h1/span[1]/text()") print(film)
代碼的運行結(jié)果,會輸出
["肖申克的救贖 The Shawshank Redemption"]
這就是最簡單的完整的爬蟲操作,通過代碼發(fā)送網(wǎng)絡請求,然后解析返回內(nèi)容,分析頁面元素,得到自己需要的東西。
這樣的爬蟲防起來也很容易。使用抓包工具看一下剛才發(fā)送的請求,再對比一下瀏覽器發(fā)送的正常請求。可以看到,兩者的請求頭差別非常大,尤其requests請求頭中的user-agent,赫然寫著python-requests。這就等于是告訴服務端,這條請求不是真人發(fā)的。服務端只需要對請求頭進行一下判斷,就可以防御這一種的爬蟲。
當然requests也不是這么沒用的,它也支持偽造請求頭。以user-agent為例,對剛才的代碼進行修改,就可以很容易地在請求頭中加入你想要加的字段,偽裝成真實的請求,干擾服務端的判斷。
import requests from lxml import etree user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)" headers = { "User-Agent" : user_agent } url = "https://movie.douban.com/subject/1292052/" data = requests.get(url,headers=headers).text s=etree.HTML(data) film=s.xpath("http://*[@id="content"]/h1/span[1]/text()") print(film)提高
現(xiàn)階段,就網(wǎng)絡請求的內(nèi)容上來說,爬蟲腳本已經(jīng)和真人一樣了,那么服務器就要從別的角度來進行防御。
有兩個思路,第一個,分析爬蟲腳本的行為模式來進行識別和防御。
爬蟲腳本通常會很頻繁的進行網(wǎng)絡請求,比如要爬取豆瓣排行榜top100的電影,就會連續(xù)發(fā)送100個網(wǎng)絡請求。針對這種行為模式,服務端就可以對訪問的 IP 進行統(tǒng)計,如果單個 IP 短時間內(nèi)訪問超過設定的閾值,就給予封鎖。這確實可以防御一批爬蟲,但是也容易誤傷正常用戶,并且爬蟲腳本也可以繞過去。
這時候的爬蟲腳本要做的就是ip代理,每隔幾次請求就切換一下ip,防止請求次數(shù)超過服務端設的閾值。設置代理的代碼也非常簡單。
import requests proxies = { "http" : "http://111.155.124.78:8123" # 代理ip } user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)" headers = { "User-Agent" : user_agent } url = "https://movie.douban.com/subject/1292052/" res = requests.get(url = http_url, headers = headers, proxies = proxies)
第二個思路,通過做一些只有真人能做的操作來識別爬蟲腳本。最典型的就是以12306為代表的驗證碼操作。
增加驗證碼是一個既古老又相當有效果的方法,能夠讓很多爬蟲望風而逃。當然這也不是萬無一失的。經(jīng)過多年的發(fā)展,用計算機視覺進行一些圖像識別已經(jīng)不是什么新鮮事,訓練神經(jīng)網(wǎng)絡的門檻也越來越低,并且有許多開源的計算機視覺庫可以免費使用。例如可以在python中引入的tesseract,只要一行命令就能進行驗證碼的識別。
import pytesseract from PIL import Image ... #get identifying code img ... im=Image.open("code.png") result = pytesseract.image_to_string(im)
再專業(yè)一點的話,還可以加上一些圖像預處理的操作,比如降噪和二值化,提高驗證碼的識別準確率。當然要是驗證碼原本的干擾線, 噪點都比較多,甚至還出現(xiàn)了人類肉眼都難以辨別的驗證碼(12306),計算機識別的準確度也會相應下降一些。但這種方法對于真實的人類用戶來說實在是太不友好了,屬于是殺敵一千自損八百的做法。
進階驗證碼的方法雖然防爬效果好,但是對于真人實在是不夠友好,開發(fā)人員在優(yōu)化驗證操作的方面也下了很多工夫。如今,很多的人機驗證操作已經(jīng)不再需要輸入驗證碼,有些只要一下點擊就可以完成,有些甚至不需要任何操作,在用戶不知道的情況下就能完成驗證。這里其實包含了不同的隱形驗證方法。
有些隱形驗證采用了基于JavaScript的驗證手段。這種方法主要是在響應數(shù)據(jù)頁面之前,先返回一段帶有JavaScript 代碼的頁面,用于驗證訪問者有無 JavaScript 的執(zhí)行環(huán)境,以確定使用的是不是瀏覽器。例如淘寶、快代理這樣的網(wǎng)站。通常情況下,這段JS代碼執(zhí)行后,會發(fā)送一個帶參數(shù)key的請求,后臺通過判斷key的值來決定是響應真實的頁面,還是響應偽造或錯誤的頁面。因為key參數(shù)是動態(tài)生成的,每次都不一樣,難以分析出其生成方法,使得無法構(gòu)造對應的http請求。
有些則更加高級一些,通過檢測出用戶的瀏覽習慣,比如用戶常用 IP 或者鼠標移動情況等,然后自行判斷人機操作。這樣就用一次點擊取代了繁瑣的驗證碼,而且實際效果還更好。
對于這類的反爬手段,就輪到selenium這個神器登場了。selenium是一個測試用的庫,可以調(diào)用瀏覽器內(nèi)核,也就是說可以打開一個真的瀏覽器,并且可以手動進行操作。那就完美可以完美應對上述兩種隱形驗證手段。
selenium的使用也很簡單,可以直接對頁面元素進行操作。配合根據(jù)頁面元素等待頁面加載完成的時延操作,基本上把人瀏覽頁面的過程整個模擬了一遍。而且因為selenium會打開一個瀏覽器,所以如果有點擊的驗證操作,一般這種操作也就在開始的登錄頁會有,人來點一下就是了。
from selenium import webdriver browser = webdriver.Chrome() browser.get("url") #獲得dom節(jié)點 node = browser.find_elements_by_id("id") nodes = browser.find_elements_by_css_selector("css-selector") nodelist = browser.find_elements_by_class_name("class-name") #操作dom元素 browser.find_element_by_xpath("xpath-to-dom").send_keys("password") browser.find_element_by_xpath("xpath-to-dom").click() #等待頁面加載 locator = (By.CLASS_NAME, "page-content") try: WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(locator)) finally: driver.close()
這么看起來仿佛selenium就是無解的了,實際上并不是。較新的智能人機驗證已經(jīng)把selenium列入了針對目標中,使得即使手動點擊進行人機驗證也會失敗。這是怎么做的呢?事實上,這是對于瀏覽器頭做了一次檢測。如果打開selenium的瀏覽器控制臺輸入window.navigator.webdriver,返回值會是“true”。而在正常打開的瀏覽器中輸入這段命令,返回的會是“undefined”。在這里,我找到了關(guān)于webdriver的描述:navigator.webdriver
)。可以看到,webdriver屬性就是用來表示用戶代理是否被自動化控制,也就是這個屬性暴露了selenium的存在,人機驗證就無法通過。而且,這個屬性還是只讀的,那么就不能直接修改。當然硬要改也不是不行,通過修改目標屬性的get方法,達到屬性修改的目的。這時的webdriver屬性就是undefined了,然后再進行智能人機驗證,就可以通過了。但這是治標不治本的,此時如果瀏覽器打開了新的窗口,或者點擊鏈接進入新的頁面,我們會發(fā)現(xiàn),webdriver又變回了true。當然,在每次打開新頁面后都輸入這段命令也可以,不過事實上,雖然點擊驗證可以被繞過去,但如果直接在頁面中加入檢測webdriver的JS代碼,一打開頁面就執(zhí)行,那么在你改webdriver之前,網(wǎng)站已經(jīng)知道你到底是不是爬蟲腳本了。
道高一尺,魔高一丈。事實上即使這樣的反爬手段,也還是可以繞過去。在啟動Chromedriver之前,為Chrome開啟實驗性功能參數(shù)excludeSwitches,它的值為["enable-automation"],像這樣
from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = ChromeOptions() option.add_experimental_option("excludeSwitches", ["enable-automation"]) driver = Chrome(options=option) driver.get("url")
這時候,不管怎么打開新頁面,webdriver都會是undefined。對于這個級別的爬蟲腳本,還不知道要怎么防御,檢測的成本太高了。
不過,事實上,換個思路,還有一些有趣的反爬方法。比如貓眼電影的實時票房和起點中文網(wǎng),在瀏覽器里能看到內(nèi)容,但是打開網(wǎng)頁代碼一看,全變成了方塊。這就是一種很好地反爬方法,簡單地說就是后端搭一套字體生成接口,隨機生成一個字體,然后返回這個字體文件,以及各個數(shù)字的unicode對應關(guān)系,前端頁面進行數(shù)據(jù)填充,就可以隱藏敏感數(shù)據(jù)。
還有些充分利用了css進行的反爬,腦洞更大。搞兩套數(shù)據(jù),顯示的時候用css定位將真實的覆蓋假的。或者搞一些干擾字符,顯示的時候?qū)pacity設為0進行隱藏。甚至還有設置一個背景,讓它和顯示的內(nèi)容拼接在一起,成為真正要展示的內(nèi)容。這些都是非常有趣的反爬手段。
不過對于前端來說,畢竟所有的數(shù)據(jù)和代碼,都給到了客戶端,爬蟲腳本總是能想出辦法來爬到數(shù)據(jù),各種反爬的手段,也就是加大爬數(shù)據(jù)的難度而已。主要還是要自覺,拒絕惡意爬蟲。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/45165.html
摘要:之前在學校曾經(jīng)用過的方法做過一些爬蟲腳本來玩,從正式轉(zhuǎn)前端之后,出于興趣,我對爬蟲和反爬蟲又做了一些了解,并且做了一些爬蟲攻防的實踐。爬蟲腳本通常會很頻繁的進行網(wǎng)絡請求,比如要爬取豆瓣排行榜的電影,就會連續(xù)發(fā)送個網(wǎng)絡請求。 之前在學校曾經(jīng)用過request+xpath的方法做過一些爬蟲腳本來玩,從ios正式轉(zhuǎn)前端之后,出于興趣,我對爬蟲和反爬蟲又做了一些了解,并且做了一些爬蟲攻防的實踐...
摘要:極簡爬蟲攻防戰(zhàn)紀要爬蟲是構(gòu)建搜索引擎的基礎負責抓取網(wǎng)頁信息并對網(wǎng)頁識別分類及過濾。爬蟲方終于鎖定了第一場戰(zhàn)役的勝局由于斷崖式技術(shù)的出現(xiàn),反爬方在瀏覽器識別戰(zhàn)役上望風披靡。經(jīng)過反爬方的精心運作,逐漸有效削弱了敵方的攻勢。 極簡爬蟲攻防戰(zhàn)紀要 ? ??爬蟲是構(gòu)建搜索引擎的基礎, 負責抓取網(wǎng)頁信息并對網(wǎng)頁識別、分類及過濾。我們熟識的電商、搜索、新聞及各大門戶網(wǎng)站都有強大的爬蟲集群在每...
摘要:而搜索引擎如百度和微軟搜索,搜索等通過什么方式才能收錄我們的個人網(wǎng)站呢答案是搜索引擎的網(wǎng)絡爬蟲。網(wǎng)絡爬蟲是一個很形象的名詞,是屬于搜索引擎的工具,只有被這些網(wǎng)絡爬蟲爬過的內(nèi)容才有機會出現(xiàn)在對應搜索引擎的搜索結(jié)果中。 不知道廣大程序員朋友們注意到一個現(xiàn)象么?使用百度是無法搜索到淘寶網(wǎng)的網(wǎng)頁。為什么會造成這種現(xiàn)象?這就要從網(wǎng)絡爬蟲說起了。 咱們程序員假如自己搭設個人網(wǎng)站,在上面分享少量自己...
摘要:摘要今年的先知白帽大會,與會者將能夠親身感受到非常多有趣的技術(shù)議題,如在國際賽事中屢奪佳績的團隊,其隊長將親臨現(xiàn)場,分享穿針引線般的漏洞利用藝術(shù)。從數(shù)據(jù)視角探索安全威脅阿里云安全工程師議題解讀本議題討論了數(shù)據(jù)為安全人員思維方式帶來的變化。 摘要: 今年的先知白帽大會,與會者將能夠親身感受到非常多有趣的技術(shù)議題,如HITCON在國際賽事中屢奪佳績的CTF團隊,其隊長Orange將親臨現(xiàn)場...
閱讀 2789·2021-11-24 09:39
閱讀 2548·2021-11-23 09:51
閱讀 1802·2021-11-17 09:33
閱讀 1737·2021-10-22 09:54
閱讀 1870·2021-08-16 11:00
閱讀 3420·2019-08-30 15:53
閱讀 1733·2019-08-30 13:19
閱讀 2901·2019-08-30 12:49