python高級—— 從趟過的坑中聊聊爬蟲、反爬、反反爬,附送一套高級爬蟲試題
- 2019 年 10 月 3 日
- 筆記
前言:
時隔數月,我終於又更新部落格了,然而,在這期間的粉絲數也就跟著我停更部落格而漲停了,唉
是的,我改了部落格名,不知道為什麼要改,就感覺現在這個名字看起來要洋氣一點。
那麼最近到底咋不更新部落格了呢?說起原因那就多了,最主要的還是沒時間了,是真的沒時間,前面的那些系列部落格都還沒填坑完畢的(後續都會填上的)
最近有點空餘就一直在開發我的項目,最近做了兩個項目:
IPproxy,看名字就知道啦,就是一個ip代理池,爬取了各大免費的代理網站,然後檢測可用性,github地址 相關的介紹github上已經說明了
get_jobs,爬取了幾十個招聘類網站的數據,github地址 同樣的,相關的介紹github上已經說明了
根據以上爬取的大概也許可能接近上百個網站吧,加上我初學爬蟲的時候爬的網站,現在也算是爬了有接近上千個網站了,對爬蟲也算是小有心得了,下面就開始說說吧
以下是總結式的解析,個人覺並不太適合零基礎的朋友,也不會有過多的圖文展示,當然我也會盡量的把問題說清楚點,而且我也不是爬蟲大佬,只是根據最近的爬蟲經歷總結出的經驗,我確實不太建議零基礎的朋友往下看,你可以先看看我之前的部落格文章或者看其他大神的文章之後再來看我這篇,因為爬蟲涉及了前端和後端還有前後端之間的交互等的技術,一些底層的原理之類的,不是說不給零基礎的朋友看,是如果沒這些知識做基礎可能看不懂(不是瞧不起小白的意思,我也是小白過來的)。當然爬蟲界的大佬們如果偶然點開,那還請多多包涵,我目前技術確實還有待提升
爬蟲前提:
1.法律問題
最近時不時總是冒出一兩個因為爬蟲入獄的新聞



不一一截圖了,自己網上搜吧,其實現在越來越多了
有朋友要說,“為什麼我學個爬蟲都被抓嗎?我犯法了嗎?” 這個目前還真的不好說,主要是什麼,目前爬蟲相關的就只有一個robots協議,而我們都知道robots協議是針對於通用爬蟲而言的,而聚焦爬蟲(就是我們平常寫的爬蟲程式)則沒有一個嚴格法律說禁止什麼的,但也沒有說允許,所以目前的爬蟲就處在了一個灰色地帶,而很多情況下是真的不好判定你到底是違法還是不違法的。好消息是,據說有關部門正在起草爬蟲法,不久便會頒布,後續就可以按照這個標準來進行了。
2.爬蟲分類:
上面說了,有通用爬蟲和聚焦爬蟲
通用爬蟲:
針對於百度,搜狗,Google這類搜索引擎類的爬蟲程式
聚焦爬蟲:
又名定向爬蟲,就是我們平時寫的針對某個需求或者某個問題而寫的程式
3.爬蟲能爬什麼數據:
一句話,所見即所得,什麼意思,你用瀏覽器能訪問,能查看的網頁數據,用爬蟲就可以爬到,反過來,你瀏覽器都無法訪問的,爬蟲是無法爬到的,除非你用一些違法的手段獲取到
舉個例子:
- 你用瀏覽器打開百度,打開淘寶,可以看到的一切數據,爬蟲都可以獲取到
- 你有優酷的vip帳號,你可以用瀏覽器看vip影片,那麼爬蟲也可以獲取到
- 你沒有優酷的vip帳號,你無法查看vip影片,爬蟲也就無法獲取到
我知道有一部分圈子裡的朋友之間流傳著有什麼破解vip之類的,那種其實也是符合所見所得的,你沒有vip,別人有啊,假如一個已有vip帳號的人把影片下載下來上傳到雲伺服器A,然後你訪問某個網站,網站後台請求的是雲伺服器A,最後呈現影片數據給你,不說了,扯遠了
爬蟲工具:
一.工具分類:
分類看以什麼分了,有自動的,有手動的,有在線的,有離線的,有傻瓜式的,有非傻瓜式的,有分析輔助為主的,有自開發式的,看每個人怎麼定義了
傻瓜式的:
比如什麼八爪魚,爬山虎,啥啥的一大堆,在線的傻瓜式的工具,根據提示點點滑鼠,輸入幾個字就完了,但是這種工具普遍得到的結果不是很理想
分析類的:
以下的都是作為輔助分析整個請求過程的工具
- fiddler :常用的抓包分析工具
- charles:和fiddler類似,優點是可以自定義上下行網速、代理、反向代理,且配置簡單、可解析AMF協議數據
- wireshark:網路封包分析軟體,功能非常強大,但是在爬蟲層面來說,輔助的意義不算大
- burpsuite:類似fiddler,但是功能更多更具體,且這個包在網路安全行業來說是個必不可少的大殺器
- .......
而需要點技術的就是自開發式的,比如自己藉助某個開發語言寫爬蟲程式(或者說腳本)就是了
二.自開發式的哪些開發語言可以作為爬蟲
其實還挺多的
- php
- javascript —— node.js
- java
- python
- golang
php寫爬蟲是可以的,但是多執行緒多進程不太支援,所以針對大型一點的項目不夠理想
nodejs的curl工具也是可以寫爬蟲的,有什麼優缺點我暫時不知道,我沒用過
java的話,聽大佬說的,寫出來的爬蟲程式很臃腫,不是說不好哈,我暫時只是有耳聞,沒用過
golang天生支援高並發,性能提升很多,也可以做爬蟲,這個我暫時只是有耳聞,沒用過
python的話寫爬蟲真的是一種神器般的存在,目前網上的爬蟲程式,可能百分之八九十都是用Python寫的
其他語言只要支援網路服務應該都可以寫爬蟲,這裡就不多說了
三.python的哪些相關的工具可以寫爬蟲
自帶的庫:
python2下:
- urllib
- urllib2
- urllib3
- httplib
- htttplib2
- re
- ......
python3下:
- urllib
第三方的庫:
- requests
- crawley
- protia
- newspaper
- pyspider
- python-goose
- scrapy
- scrapy-redis
其他相關的庫:
- lxml
- json
- beautifulsoup
- re
- pyquery
- execjs
- js2py
目前就想到這麼多
平常的話,做網路交互我就用requests庫,但是有些小問題,用多了的人應該都知道,requests庫里的異常類不夠全,有時候報錯了無法捕獲
做數據解析的話我用json,re , lxml, beautifulsoup,pyquery,execjs,js2py都有在用,只要有場景需要就會用
大型項目就上scrapy,需要分散式就上scrapy-redis
四.爬蟲中常見的問題,常見的反爬機制
其實我之前轉載過一篇爬蟲相關的文章 打造一個健壯高效的網路爬蟲 ,轉載的爬蟲大佬崔慶才的文章,他的文章總結性就非常強了,各種層面都涉及了,我還要自己再寫一篇的原因就是,下面的問題真的是我親身經歷的問題,以下的有些問題很可能對有些老哥還說不算問題,各有各的開發思路,按照我那樣的思路也許就會遇到這些問題,一來是做個記錄,二來是幫助那些遇到跟我同樣問題的朋友。
重頭戲終於來了,哈哈,我也有點按奈不住了
1.請求頭之User-agent
這個稍微接觸過一點點爬蟲的應該都不陌生,不是說接觸Python爬蟲,不管你用什麼開發語言來寫爬蟲,應該都會用到這個。大概解釋一下,就是一個身份的象徵,這個可以用瀏覽器自帶的調試工具查看,訪問一個網站的時候,按f12鍵或者滑鼠右鍵打開調試(有的瀏覽器叫檢查,或者查看元素),然後切換到network(網路),重新刷新一次網站,就會出現所有的請求,隨機點擊一個,右邊出現的就是請求頭資訊了,如下,這是我訪問某某網站的,我使用的瀏覽器是火狐,然後圖上標註的就是user-agent

具體怎麼用呢?
比如:

這樣就可以帶上UA了
如果不帶的話,你的目標網站服務端是可以檢測到是瀏覽器還是爬蟲工具在訪問數據的,就看你的目標網站的友好度了,如果反爬機製做的很高效,到這裡你就被ban了
2.調試工具之痛
很多時候我們為了查看網頁的DOM結構可能就直接用瀏覽器自帶的調試工具(就是上面說的按f12鍵)來查看,這個的話,大部分網頁是可以應對的,但是,少部分網站用調試工具查看的DOM結構和整個網頁的源碼是不一致的,說個最近的事,我爬某影片網站,調試工具打開他在每個重要資訊都加了一個css樣式,這個css樣式是通過定位某個html標籤(假設為<span></span>標籤)設置上的,我解析網頁的時候就很痛苦,調了很久,就是得不到結果,最後發現這個span標籤是用js拼接上的,換句話說,服務端回應的是不帶有這個span標籤的,所以就要沒有這個span標籤來處理。說這麼多不知道看官您能不能理解,遇到過這個問題的朋友應該明白我在說什麼

3.非同步請求
上面說的DOM結構不一致還有一種可能,就是前後端用的Ajax非同步請求的,所以你打開瀏覽器的調試工具查看DOM結構和你用Python獲取的結果也是不一致的,這個相信會玩爬蟲的老哥們都不陌生
4.請求頭之Cookies
有一部分網站,當你訪問首頁時,會自動設置一個cookie,然後訪問同站下的其他頁面就會驗證這個欄位,如果不匹配就會禁止訪問
如下,訪問百度都會自動設置一些cookie:

5.請求頭之特殊欄位
特殊欄位是什麼呢,就是某網站特有的一些欄位,比如以下的boss直聘網:

會帶有這些特殊的欄位。當然這裡只是舉個例子,,經過我的測試,我圈出來的那幾個[:method]等的欄位其實請求的時候是不用帶上的
6.請求頭之Referer
這個referer是幹嘛的呢?首先該欄位的值都是上一級網站的url,根據我的理解,它有以下作用:
1.做前端的朋友知道,可以借用這個欄位直接返回到上個頁面
2.還可以通過這個追蹤流量來源,比如某某公司在百度上做了SEO(打了個推廣廣告),當用戶通過百度點進來的話,就可以通過referer追蹤來源,對用戶做進一步的行為分析
3.檢測來源的合法性,因為都可以知道通過某某url路徑過來的,那麼就可以判斷來源是否合法,如果異常的話就可以做攔截請求等等的

有的網站就是因為有這個驗證,所以返回的數據不正常,帶上就OK了。還有的網站更奇怪,你不帶上也不會報錯,返回的數據也是希望的數據,但是無法和頁碼匹配,比如你請求的是第一頁的數據,它有可能返回的是第5頁的數據。遇到過這個問題的老哥應該知道我在說什麼
7.請求頭之accept:
不知道老哥您遇到過這個問題沒有,在請求頭裡,如果服務端返回的結果是普通的html頁面的話,值就應該是如下的:
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', 如果返回的是json字元串(返回json字元串的話,往往是屬於非同步請求)的話,值就應該是這個:
'Accept': 'application/json, text/javascript, */*; q=0.01',
這個不知道你們有沒有體會,反正我記得我爬某網站的時候,因為都通用的同一個請求頭,有的網站就是返回json數據,我怎麼改程式碼都無法得到正確的值,就是因為本來是json字元串的我的accept用的上面的html頁面用的,導致返回數據不符合事實。
8.請求頭之Connection

這個欄位字面意思就是http連接嘛,http鏈接最根本的就是tcp/ip連接了,什麼三次握手,四次握手之類的,這些就不展開了,要說就占篇幅了。我們都知道,http請求屬於短連接,訪問就有,關閉瀏覽器就會自動斷開的,這種就是短連接,對應的長連接就是websocket,這個就不展開了,自行百度了。這個Connection欄位有兩個值,一個是keep-alive,一個是close,keep-alive的話往往就跟前面的帶有cookie相關,他會保存session會話(如果關閉瀏覽器的話就沒了,有的網站是保存一個欄位,默認有幾天的有效期),作為同一個連接來請求另一個頁面,如果是close的話,就是每次訪問都是重新和服務端建立一個連接,不會保存session
這個問題的話,在一般情況下還是不會遇到,主要就是在高並發請求的時候,有可能同一個時刻請求多次來自同一個站點的數據,觸發該網站的反爬機制的頻率限制,就會出現什麼scoket.timeout,urllib3.connection.HTTPConnection之類的錯誤。所以從那次之後我的爬蟲程式如果用了高並發的話,我都會把這個connection設置為close
9.返回數據gzip

gzip的意思就是這個網站的數據是做呀gzip壓縮的,在瀏覽器(客戶端)訪問之後,會自動處理這類格式的數據。但是使用Python的標準款urllib的話,是不會處理這類格式的, 解決方法就是用requests庫,會自動處理gzip格式,反正這個庫真的太強大了
10.reqeusts庫的弊端
嘿嘿,剛說完requests很強大,馬上說它的弊端,是的,就是這麼騷氣。它有什麼弊端呢,如果經常使用requests庫作為主要的網路請求的話,使用時間越長的老哥,就越會發現它有個弊端,就是它封裝的異常類不夠全,在報錯各種各樣的異常的時候,它有時候捕獲不到,無法進行針對性的處理,這就是它的弊端,這個怎麼解決呢,目前我的話,沒有一個很好的解決方法,只能用Exception或者BaseException類來捕獲。
當然這個問題也不是一定會遇到,有時候只是某個其他的異常爆出,導致後續的程式碼跟著出錯,然後跟著拋出異常,所以也不能盲目的用異常基類來捕獲
11.登錄驗證
有的網站為了解決網路請求的擁塞,就做了帳號登錄驗證,你必須登錄帳號之後才能正常訪問頁面,一般的網站登錄之後返回的就是上面說的cookie欄位,有的也會返回一個特殊的欄位作為驗證,我記得百度登錄之後用的欄位是BAIDUID。這個不需要多說什麼,找到登錄介面,提交帳號密碼參數訪問登錄介面就行了
12.請求頭之token
這個token在語義上就是個令牌的意思,用的比較多的地方就是在手機端上用token驗證,此手機端的驗證對應的電腦端用的session驗證,而電腦端用token的情況就是,特殊欄位的變異,有的網站就放在請求頭的authorized鍵里,值就是token,用uuid生成的,有的就是自定義的鍵,比如boss直聘的就是__zp_stoken__,必須要帶上這個欄位才能爬取(因為boss直聘的反爬機制升級了,以前直接可以爬,現在必須帶上這個欄位才行,說句題外話,目前我還沒找到boss直聘這個欄位是怎麼生成的,用fiddler抓包發現請求了阿里雲的服務端,但是返回的數據是空,反正沒找到它是怎麼生產的)

13.登錄驗證+token
有的網站在用戶登錄之後感覺還不夠安全,就會再對token驗證,如果登錄驗證和token都通過了說明是正常登錄操作,才放行。當然也有的網站不需要登錄也會分配一個token,比如上面的boss直聘,這個就不多說了,就是以上的結合
14.設備驗證(手機,電腦)
一般情況下,電腦能訪問的頁面,手機一定能訪問,只是如果該站沒有作響應式的話,用手機訪問的頁面排版很亂,因為手機和電腦的尺寸不一樣嘛。
但是手機能訪問的,電腦不一定能訪問,比如某app,或者微信小程式,它會做設備驗證,發現不是手機頁面的話就會攔截或者提示讓你用手機下載該app查看。有朋友要問了,是用的什麼來檢測你是手機還是電腦的呢?就是前面最開始說的User-agent,說到這,怎麼解決這個問題不用多說了吧,同樣的偽造成手機的UA就行了,當然如果是針對app的爬取的話,一般就在電腦上下載模擬器(夜神模擬器啥啥的),然後fiddler抓包分析,然後再爬取
15.重定向
這個跟http的狀態碼有關了,不多說,返回的狀態碼是3**的就是重定向範疇里的,比如下面的百度:

這種網站怎麼爬取呢,requests會自動處理重定向的問題,沒錯,requests就是這麼抗打
16.觸發跳轉到新的標籤頁
什麼意思呢,就是比如我在某一個網站點一下按鈕,觸發機制,用新的網頁標籤打開的,前端的朋友應該知道,就是a標籤屬性里加了個target='_blank',這種的話,如果用瀏覽器的調試工具來分析的話就無法即時的查看請求了。因為習慣上我喜歡用瀏覽器自帶的調試工具分析,比較方便快捷,實在不行的話就上fiddler啥的抓包工具。沒錯,解決方法我已經說了,像這種點擊一個會以新的瀏覽器窗口打開的就用抓包工具來分析
17.調試工具觸發js的debug監聽器
這個我不知道你們遇到過沒,我有一次抓某個網站,它就是為了防止我這類瞎jb搞的人分析它的程式碼,分析它的請求過程,所以當我一打開調試工具,就觸發它的監聽器,然後我就發現我電腦的CPU立馬跑滿了,一直在消耗我的電腦資源直到電腦卡死,所以我只能感覺關閉調試工具或者關閉瀏覽器,實在不行只能重啟了,它就是監聽的debuger,我不知道這個是一個函數還是一個類,以下是我保存的程式碼,看有緣人能不能看懂,看懂的話我就以身相....,不對,走錯片場了,卧槽。。。
var check = (function () { var callbacks = [], timeLimit = 50, open = false; setInterval(loop, 1); return { addListener: function (fn) { callbacks.push(fn); }, cancleListenr: function (fn) { callbacks = callbacks.filter(function (v) { return v !== fn; }); } } function loop() { var startTime = new Date(); debugger; if (new Date() - startTime > timeLimit) { if (!open) { callbacks.forEach(function (fn) { fn.call(null); }); } open = true; window.stop(); } else { open = false; } } })();
18.js加密cookie
這個大概的原理就是,訪問該網站的時候會訪問兩次,第一次服務端返迴響應頭裡給了一段加密的js程式碼,前端(瀏覽器)自動調用js然後反解出cookie,然後第二次訪問的時候帶上cookie去訪問,才會返回一個正常的值,這個我在寫IPproxy項目的時候遇到的66ip(http://www.66ip.cn/)網站就是這樣的,而且很多同類的網站都是類似的操作。解決方法就是打開瀏覽器的調試工具,然後打斷點測試,看看流程,基本都會有一系列的操作然後賦值給一個變數,找到這個變數名被如果的替換就行了,主要的破解難點就在js的部分,有的是做了js混淆加密的,有的是做了自定義處理的,這個就只有多嘗試了
說到這,如果是上面的監聽debug工具的+js加密的話,那可就真的難操作了,你一打開調試工具想打斷點分析,結果就立馬卡死了。哈哈哈,好像我還沒有遇到網站這麼乾的
相關的js加密cookie破解教程,可以移步這裡:https://www.cnblogs.com/zdfbk/p/8806282.html
19.urllib庫之編碼
有的時候如果要傳遞參數到服務端的話,那麼就得做url編碼,使用url編碼解碼就可以用urllIb.parse.quote和urlib.parse.unquote,使用quote方法作編碼的話,默認使用的是utf-8的編碼,但有時候一些網站用的gbk,所以這是一個坑,你得用quote(kw,encoding='gbk')才能轉為gbk的編碼,不熟悉這個的話就很難發現這個,因為我們一般就直接用quote就行了,根本不在意是用了什麼編碼

20.request.post之痛
嘿嘿,又是requests庫的問題,準確說其實不是requests的問題,而是跟上面的quote一樣,我們平常遇到的網站基本都是不會出現這個情況,當出現的時候我們就傻眼了,requests庫的粉絲們,放下你們手上的菜刀,我是友軍啊,我也一直在用requests,只是發現了這一兩個情況而已
不多說了,requests做post請求時,提交的data欄位會默認將data欄位作url編碼,且默認用的utf-8編碼,對的,又是編碼的鍋,而有的網站用的並不是utf-8編碼的,假如某網站用的是gbk編碼,如果我們還是默認的操作的話,就會出錯,解決辦法就是,手動編碼:

21.xpath解析tbody
解析網頁結構的工具很多,比如一大殺氣正則表達式,然後就是xpath,再然後就是bs4,最近我痴迷於xpath,我覺得寫起來異常的順暢,非常有感覺,但是在其中還是遇到了問題如下,無法解析帶有tbody標籤,這個是我最近發現的,不知道是不是版本問題,只要網頁的DOM結構用tbody,比如table標籤下有tbody/tr/td時,我要取td下的數據,按理就是寫的response.xpath('//table/tbody/tr/td/text()'),但是這樣寫就是TMD的拿不到,得去掉tbody,寫成這樣就可以拿到:response.xpath('//table/tr/td/text()'),總之就是不能帶tbody,如果有就直接跳到下一級就行,我估計是這個tbody被錯誤的解析成body標籤了
22.xpath元素選取
一般情況下,我們獲取某個數據的話,直接就根據class屬性或者id屬性,反正就一些非常特定的屬性三兩下就可以定位元素,但是有的元素就是什麼屬性都沒帶的,就只是一個標籤名,而且這個標籤用的還異常的多,此時此刻的話,你就可以你的目標元素就近的標籤有沒有很特殊的屬性,直接就可以定位的,然後用following-sibling定位兄弟元素即可,比如:following-sibling::span[1]/text(),補充一個:回到上級:用 【..】表示回到上級,再補充一個,用contains(text(),'xxx'):根據一個元素的內容包含某個欄位來定位
當然這幾個都是很簡單的,這個本來就是xpath的基礎部分,但是我跟你說,這三個配套使用的話就沒有鎖定不了的元素,通通一殺一個準,真的,我感覺用多了xpath,比用beautifulsoup還順手
23.簡單驗證碼
簡單驗證碼,比如一些肉眼很好看出的驗證碼的話,可以借用tesseract庫來識別,做ocr提取,比如以下就是我那個IPproxy里的某一段程式碼:

直接就可以把簡單的驗證碼的數據提取出來,更多的操作就不說了,網上一大堆
24.滑動驗證碼
滑動驗證碼的話,以極驗的滑動驗證碼為典型,之前網上有一大堆的極驗驗證碼破解,不過都是2.0的破解,更新到3.0之後,破解的人就少了,不過,嘿嘿,我還是破解了,
我不多說,感興趣的可以看看我的源碼,包括騰訊系的我也破解了:GitHub (就在我的github里,我不說是哪個,嘿嘿,皮一把)
網易系的就不多說了,坊間傳聞的,網易的滑動驗證碼本來就是抄襲極驗的(不是我說的),所以破解方法差不多,感興趣的可以根據我的程式碼自行修改
25.ip代理
終於說到這個問題了,稍微接觸過爬蟲的人都知道,你知道訪問頻率太頻繁你電腦的公網IP就會被ban的,那麼你就需要用上ip代理防止ip被ban無法繼續爬數據的,也不多說,各位老哥如果需要請用滑鼠滑到這篇文章的頂部,有寫好的,現成的哦,不定期更新程式碼哦~
26.訪問頻率控制
有的網站比較大型,每天的訪問量很大,那麼這個網站對訪問頻率的限制就沒那麼嚴格,如果是小網站限制就會嚴一點,當然凡是無絕對,這個真的就看你的感知了,你如果感覺按你的程式碼運行下去可能爬不了幾個數據就請求超時了,多半是觸發訪問頻率的峰值了。如何解決,就只能看你自己怎麼優化程式碼,保證程式碼每次請求的都不走空了,這個就沒法具體的說了,你可以用協程來回的切換啥啥的
27.提升性能:
提升性能的話,要說的還挺多的,我就說幾個比較典型的,如果你發現你的程式碼運行是串列的,你可以用gevent協程做切換,或者用執行緒池,或者用執行緒池+非同步的方法,然後網路請求屬於IO操作,所以不適合上多進程的方式
如果你還覺得速度不夠快,可以棄掉requests庫改用aiohttp庫,這個也是網路請求的庫,不過是非同步請求的,requests是阻塞式的請求
還覺得不夠快,可以用JIT,即使編譯技術,把你覺得比較耗時間的程式碼塊用上JIT
還覺得不夠快,可以再用上解釋器來直接解釋這段程式碼,比如win平台下,直接用cpython對你的程式碼進行處理,其他平台的就用其他平台的解釋器了,不多說了
還覺得不夠快,技術再強點的話,可以寫原生的C程式碼,把幾個關鍵的操作抽離出來,用C來重構,然後運行的使用直接調用這段C程式碼(python有直接運行C程式碼的庫,很多,網上自行查詢)
還覺得不夠快,升級你的硬體配置了
還覺得不夠快?卧槽,沒完了是吧,已經這樣了,還想怎麼個優化法啊老鐵?
好的,以上就是我遇到的問題,在這過程中,有可能會遇到一些非常奇葩的問題,你簡直無從下手的,然後慢慢找原因,找為什麼,這樣發散式的,又學到了新的東西。通過爬蟲,我也對Python有了新的理解,新的體悟,從問題中成長,得到提升還是不錯的
爬蟲還有沒有更高級的技術層面
確切的說,一定有的,據我目前的水平來理解的話,爬蟲研究到一定層面的話,還跟網路安全有聯繫,比如跟逆向工程就有聯繫,逆向分析一個網站或者app什麼的,我是真的覺得爬蟲要研究透,估計得爬到上萬的網站/app才敢說通透了。好的,以下分享一套爬蟲題,這個是我關注的一個爬蟲大佬(人稱亞一爬,微博:梁斌penny)發的一套題,裡面就有涉及網路安全的東西,感興趣的可以自己做一下,先說明,我這裡沒有答案的哈,自行百度查看答案
1. 使用python中的requests庫時(目前版本v2.22),以下哪種說法不正確:
A. 支援自定義請求中的headers順序
B. 支援不同域名使用不同代理
C. 支援http2
D. 支援socks代理
2. 一般來說, python的requests.get函數會對傳入的url進行urlencode操作. 但當如下程式碼中的keyword為哪個選項時, 無法得到預期的結果:
程式碼:requests.get('https://baike.baidu.com/item/{}'.format(keyword))
A. '梁斌'
B. 'C# 入門經典'
C. 'r&b'
D. '川上とも子'
3. 如果進行大規模並發抓取(比如1000並發+,單核單進程),下面哪個python的庫的效率最好的:
A. urllib
B. requests
C. http.client
D. aiohttp
4. 使用Chrome devtools控制單個Chrome瀏覽器進行自動化操作時(原生chrome,且不使用插件的情況下),以下哪個說法正確的是:
A. 不能控制Chrome中的多個窗口
B. 不能抓取來自網路層的原始數據
C. 不能動態切換Chrome的代理
D. 不能禁止圖片載入
5. 以下對於Chrome headless模式的描述中,哪個是錯誤的?
A. headless模式的User-Agent與普通(非headless)模式是不一樣的
B. headless模式是有BOM和DOM的
C. headless模式是不支援Webassembly的
D. headless模式是支援滑鼠點擊事件的
6. 下列那種加密方式能最大限度抵禦彩虹表的爆破:
A. HMAC-MD5
B. MD5
C. MD4
D. SHA1
7. 現在很多app採用了證書鎖定ssl pinning來防止中間人攻擊,關於ssl pinning下列說法錯誤的是:
A. ssl pinning是將服務端證書打包內置到移動客戶端中,HTTPS連接建立時與服務端返回的證書對比一致性,以確定這個連接的合法性
B. 採用ssl pinning的app,仍然可以直接使用mitm proxy,fiddler等抓包工具可獲取到明文包
C. 使用frida等工具繞過證書鎖定後,抓包工具才能獲取到明文HTTPS數據包
D. 採用了ssl pinning證書鎖定的app,內置證書一般為自簽名證書
8. 以下對xposed的描述中,正確的是:
A. xposed是對內核中init進行修改,使其能夠注入到任何進程中
B. xposed不能hook native中的函數
C. xposed中的XposedBridge.jar會出現在任意apk進程的/proc/self/maps中
D. xposed並不支援Android Oreo的版本
9. 以下哪條語句能在frida中輸出2019, Pet類定義如下:
public class Pet {
private static int kind = 2019;
private static int kind()
{
return 9102;
}
}
A. console.log( Pet._kind );
B. console.log( Pet.kind );
C. console.log( Pet._kind.value );
D. console.log( Pet.kind.value );
10. 關於app反調試下列說法錯誤的是:
A. app可以通過ptrace自身,來阻止調試器ptrace附加到app進程實現反調試
B. 在對程式脫殼過程中,經常需要將/proc/pid/mem或者/proc/pid/maps下記憶體數據dump出來, 可以使用inotify對文件進行監控,如果發現文件系統的的打開,讀寫,可能程式在被破解,就可以執行kill進程操作
C. 通過遍歷程式記憶體段是否存在斷點指令,來判斷程式是否正在被調試,是則kill進程
D. 程式處於被調試狀態時,某些關鍵指令的執行速度變化不大,所以通過對比關鍵程式碼執行的前後時間差,不能夠判斷出進程是否被調試
11. 以下關於frida的使用哪項不正確?
A. java層的hook必須在java.perform中執行
B. java層同名函數的hook,可以通過不同參數數量來區分,而不用寫overload
C. frida以spawn方式啟動app可以hook app在啟動時就執行的函數
D. frida可以更改某個native函數的實現
12. 下面通過IDA反彙編的arm指令,其中描述不正確的是?
.text:0000ED72 MOVS R0, R0
.text:0000ED74 POP {R0}
.text:0000ED76 CMP R1, #0
.text:0000ED78 BNE loc_ED84
.text:0000ED7A PUSH {R0,R1,LR}
.text:0000ED7C BL sub_B2544
.text:0000ED80 MOVS R6, R1
.text:0000ED82 MOVS R0, R0
A. BL是帶返回的跳轉指令
B. 0xED7C位置進行的跳轉後LR暫存器的值為0xED81
C. sub_B2544是程式設計師定義的函數名,此處將調用sub_B2544函數
D. 0xED78位置的指令含義是如果R1 != 0則進行跳轉
13. 做爬蟲難,還是做反爬難?
發表下您的看法,並簡單闡述下原因(100字以內,開放式題目,沒有對錯,可自由發揮)。
1)下面哪種方式可以讓爬蟲合理、合法地抓取當日儘可能多的數據?
A. 通過漏洞進入他人電腦系統,把資料庫dump出來。
B. 用大量低頻關鍵詞在目標站點上搜索,獲得當日更全數據。
C. 找到熱門的hub頁,熱門的話題,熱門的帳號,獲取當日更全數據。
D. 用熱門關鍵詞在百度等搜索引擎上,用site:www.website.com + 關鍵詞 查詢,從而發現新數據
2)以下所列出的方法中,瀏覽器web數據抓取效率最高的方法是?
A. selenium + phantomjs
B. 使用chrome或者chrome內核抓取
C. 模擬web協議直接用wget或curl抓取
3)下面哪項是手機端抓取app數據相比web端的優勢(多選):
A. 手機端協議簡單容易分析
B. 手機端可以使用模擬點擊
C. 手機端就算出新版了舊版還是可以繼續使用,不會立即停掉
D. 通常來說,手機端抓取同樣資訊量的數據,下載量更低
4)下面哪些代理支援rawsocket連接(多選)?
A. HTTP代理
B. HTTPS代理
C. SOCKS4代理
D. SOCKS5代理
5)下面程式碼請求實際訪問地址url是什麼?
url = "https://test.cn/test"
params = {
"xxxx":"1234"
}
headers = {
"Host": "www.test.cn",
"Accept-Encoding": "gzip,deflate",
"Connection": "Keep-Alive"
}
requests.get(url, params, headers =headers, allow_redirects = False, verify = False)
假設http://test.cn/test?xxxx=1234返回的狀態碼302且response header里有Location:http://www.test.cn/dpool/ttt/domain.php?d=test&xxxx=1234
A. https://test.cn/test
B. https://test.cn/test?xxxx=1234
C. https://www.test.cn/test?xxxx=1234
D.http://www.test.cn/dpool/ttt/domain.php?d=test&xxxx=1234
6)假如你要爬大量youtube影片的二進位內容,存儲在本地,最佳的辦法是?
A. Mysql資料庫存儲
B. Redis存儲
C. Mongodb存儲
D. 文件系統
7)如果想爬自己手機應用上的HTTPS的數據,獲得明文,下面哪個說法是正確的?
A. 自己搭建一個HTTPS代理,讓手機設置為這個代理,即可獲得明文
B. 任何HTTPS明文都是可以獲取的
C. 在PC上建立一個無線熱點,讓手機連這個熱點,並使用Wireshare軟體分析出HTTPS的明文數據
D. 通過讓手機系統信任根證書,使用Man-in-the-middle中間人攻擊技術,就可以獲取任何HTTPS明文
8)以下哪個功能chromedriver協議不支援?
A. 注入js文件
B. 模擬滑鼠滑動
C. 網路請求的響應式處理
D. 同個實例可以同時操作多個頁面
9)爬取數據過程中,哪個情況是最不可容忍的?
A. 爬取的數據不完整,有部分數據遺失
B. 爬取程式非法關閉,記憶體泄露
C. 爬取的數據部分出錯,手動修改
D. 不同版本的數據合併在一起
10)爬蟲開發不會涉及到的技術或者知識有?
A. tcp,udp傳輸協議
B. 反彙編技術
C. 資料庫存儲
D. 音影片流解析
E. 網路路由協議
F. 以上都會涉及
1)如何獲得大量IP資源(業界主流方法)
2)如何獲得帳號資源,如何進行大量帳號登陸
3)抓取系統如何構建,如何可擴展
4)如何探測封殺閾值
5)如何將爬蟲模擬成正常用戶
6)每個模組使用到的最佳工具
7)其他系統雜項trick,如何流量均衡等等
1)爬蟲為什麼要做DNS快取?
A:可以節約抓取頻寬
B:節約域名解析時間
C: 減少下載數據大小
D:防止多次DNS請求被抓取目標網站封殺
2)Etag幹什麼用的?
A:防止重複圖片download
B:節約http header的大小
C:提示web服務可以接受壓縮數據
D:提示網頁內容的標籤資訊
3)Transfer-Encoding為chunked時,會出現什麼情況
A:通常沒有Content-Type域
B:通常沒有Content-Length域
C:網頁數據不可能同時即是壓縮數據又是chunked數據
D:數據結尾標記是:一個數值(表示總長度)rnrn
4)tcp最小數據載荷是多少位元組(拋出協議頭部)? the minimum "data" size of a TCP segment should be?
A:6位元組
B:20位元組
C:24位元組
D:不確定
5)當最後一個包比最小數據載荷還小時,TCP/IP協議如何處理是否結束?
A:在最後一個包的末尾填充特殊字元以表示數據結束
B:最開始協商的數據大小和已經接受的數據一致即可判斷結束
C:再發一個最小數據載荷大小的空包已表示數據結束
D:和具體協議實現有關,並不完全確定
6)下面那一項是爬蟲工程師不需要的
A:人工智慧
B:系統架構
C:網路相關
D:HTTP協議
E:瀏覽器
F:數據存儲
G:待遇持續保持在比較低的水平