1、作爬蟲所須要的基礎前端
要作一隻爬蟲,首先就得知道他會幹些什麼,是怎樣工做的。因此得有一些關於HTML的前置知識,這一點作過網頁的應該最清楚了。python
HTML(超文本標記語言),是一種標記性語言,自己就是一長串字符串,利用各類相似 < a >,< /a>這樣的標籤來識別內容,而後經過瀏覽器的實現標準來翻譯成精彩的頁面。固然,一個好看的網頁並不只僅只有HTML,畢竟字符串是靜態的,只能實現靜態效果,要做出漂亮的網頁還須要能美化樣式的CSS和實現動態效果的JavaScipt,只要是瀏覽器都是支持這些玩意兒的。web
嗯,咱們作爬蟲不須要了解太多,只須要了解HTML是基於文檔對象模型(DOM)的,以樹的結構,存儲各類標記,就像這樣:正則表達式
以後會用到這種思想來在一大堆HTML字符串中找出咱們想要的東西。數據庫
瞭解了這個而後還得了解網頁和服務器之間是怎麼通訊的,這就得稍微瞭解點HTTP協議,基於TCP/IP的應用層協議,規定了瀏覽器和服務器之間的通訊規則,簡單粗暴的介紹幾點和爬蟲相關的就是:瀏覽器
瀏覽器和服務器之間有以下幾種通訊方式:安全
GET:向服務器請求資源,請求以明文的方式傳輸,通常就在URL上能看到請求的參數服務器
POST:從網頁上提交表單,以報文的形式傳輸,請求資源cookie
還有幾種比較少見就不介紹了。網絡
瞭解了這兩點就能夠準備工具了,固然,對爬蟲有興趣還能夠了解一下爬蟲的發展史。
2、介紹幾款優秀製做爬蟲的輔助工具
因爲我是採用python3.6開發的,而後從上文的介紹中,也該知道了一隻爬蟲是須要從HTML中提取內容,以及須要和網頁作交互等。
若是不採用爬蟲框架的話,我建議採用:
BeautifulSoup 庫 ,一款優秀的HTML/XML解析庫,採用來作爬蟲,
不用考慮編碼,還有中日韓文的文檔,其社區活躍度之高,可見一斑。
[注] 這個在解析的時候須要一個解析器,在文檔中能夠看到,推薦lxml
Requests 庫,一款比較好用的HTTP庫,固然python自帶有urllib以及urllib2等庫,
但用起來是絕對沒有這款舒服的,哈哈
Fiddler. 工具,這是一個HTTP抓包軟件,可以截獲全部的HTTP通信。
若是爬蟲運行不了,能夠從這裏尋找答案,官方連接可能進不去,能夠直接百度下載
爬蟲的輔助開發工具還有不少,好比Postman等,這裏只用到了這三個,相信有了這些能減小很多開發阻礙。
3、最簡單的爬蟲試例
最簡單的爬蟲莫過於單線程的靜態頁面了,這甚至都不能叫爬蟲,單單一句正則表達式便可匹配出全部內容,好比各類榜單:豆瓣電影排行榜,這類網站爬取規則變化比較少,用瀏覽器自帶的F12的審查很容易找到須要爬取信息的特徵:
見到花花綠綠的HTML代碼不要懼怕,一個一個點,直到找到須要的信息就好了,能夠看到全部電影名都是在這樣
之下的,每有一個這樣的標籤就表明一個電影,從他的孩子< span >中便可抓取到電影名。
代碼以下:
抓取結果以下:
乍一看,就這麼個玩意兒,這些電影名還不如直接本身去網頁看,這有什麼用呢?可是,你想一想,只要你掌握了這種方法,若是有翻頁你能夠按照規則爬完了一頁就解析另一頁HTML(一般翻頁的時候URL會規律變化,也就是GET請求實現的翻頁),也就是說,只要掌握的爬取方法,不管工做量有多麼大均可以按你的心思去收集想要的數據了。
4、須要模擬登陸後再爬取的爬蟲所須要的信息
4.1.登陸分析
剛纔的爬蟲未免太簡單,通常也不會涉及到反爬蟲方面,這一次分析須要登陸的頁面信息的爬取,按照往例,首先打開一個網頁:
我選擇了我學校信息服務的網站,登陸地方的代碼以下:
能夠看到驗證碼都沒有,就只有帳號密碼以及提交。光靠猜的固然是不行的,通常輸入密碼的地方都是POST請求。
POST請求的響應流程就是 客戶在網頁上填上服務器準備好的表單而且提交,而後服務器處理表單作出迴應。通常就是用戶填寫賬號、密碼、驗證碼而後把這份表單提交給服務器,服務器從數據庫進行驗證,而後做出不一樣的反應。在這份POST表單中可能還有一些不須要用戶填寫的用腳本生成的隱藏屬性做爲反爬蟲的手段。
要知道表單格式能夠先試着隨便登陸一次,而後在F12中的network中查看登陸結果,如圖:
【注】若是用真正的帳號密碼登陸,要記住勾選上面的Preserve log,這樣即便網頁發生了跳轉以前的信息也還在。
從上面的兩張圖中很容易發現其中的一個POST請求, login?serv…就是登陸請求了
能夠看到這個登陸請求所攜帶的信息有:
General: 記錄了請求方式,請求地址,以及服務器返回的狀態號 200等
Response Headers: 響應頭,HTTP響應後傳輸的頭部消息
Request Headers: 請求頭,重點!!,向服務器發送請求時,發出的頭部消息,之中不少參數都是爬蟲須要模擬出來傳送給服務器的。
From Data:表單,重點!!,在這裏表單中有:
username: 12345
password: MTIzNDU=
lt: e1s1
_eventId: submit
我明明都填的12345,爲何密碼變了呢?能夠看出這密碼不是原始值,應該是編碼後的產物,網站經常使用的幾種編碼/加密方法就幾種,這裏是採用的base64編碼,若是對密碼編碼的方式沒有頭緒能夠仔細看看登陸先後頁面的前端腳本。運氣好能夠看到encode函數什麼的。
若是你不想錯過Python這麼好的工具,又擔憂自學遇到問題無處解決,如今就能夠Python的學習q u n 587-137-371能夠來了解一塊兒進步一塊兒學習!免費分享視頻資料
4.2信息提取
若是瞭解過Resquests庫的文檔就知道,發送一個通常的POST請求所須要的參數構造是這樣的:
從上面的兩張圖片中便可找到發送一個正確的請求所須要的參數,即 url 和 data :
url 即上面的 Request URL:
Request URL: http://uia.hnist.cn/sso/login?service=http%3A%2F%2Fportal.hnist.cn%2Fuser%2FsimpleSSOLogin
data 即上面的From data:
收集到了必要的信息還得了解三點:
1、登陸後的網頁和服務器創建了聯繫,因此能和服務器進行通訊,但即便你從這個網頁點擊裏面的超連接跳轉到另一個子網頁,在新網頁中仍是保持登陸狀態的在不斷的跳轉中是怎麼識別用戶的呢?
在這裏,服務器端通常是採用的Cookie技術,登錄後給你一個Cookie,之後你發出跳轉網頁的請求就攜帶該Cookie,服務器就能知道是你在哪以什麼狀態點擊的該頁面,也就解決了HTTP傳輸的無狀態問題。
很明顯,在模擬登陸之後保持登陸狀態須要用得着這個Cookie,固然Cookie在請求頭中是可見的,爲了本身的帳號安全,請不要輕易暴露/泄漏本身的Cookie
2、先了解一下,用python程序訪問網頁的請求頭的User-Agent是什麼樣的呢?沒錯,以下圖所示,很容易分辨這是程序的訪問,也就是服務器知道這個請求是爬蟲訪問的結果,若是服務器作了反爬蟲措施程序就會訪問失敗,因此須要程序模擬瀏覽器頭,讓對方服務器認爲你是使用某種瀏覽器去訪問他們的。
3、查找表單隱藏參數的獲取方式,在上文表單列表中有個lt參數,雖然我也不知道他是幹嗎的,但經過POST傳輸過去的表單確定是會通過服務器驗證的,因此須要弄到這份參數,而這份參數通常都會在HTML頁面中由JS腳本自動生成,能夠由Beautifulsoup自動解析抓取。
關於Fiddler的使用和請求信息相關信息能夠查看連接:https://zhuanlan.zhihu.com/p/21530833?refer=xmucpp
嗯,最重要的幾樣東西已經收集完畢,對Cookie和請求頭的做用也有了個大概的瞭解,而後開始發送請求試試吧~
5、開始編碼爬蟲
若是用urllib庫發送請求,則須要本身編碼Cookie這一塊(雖然也只要幾行代碼),但用Requests庫就不須要這樣,在目前最新版本中,requests.Session提供了本身管理Cookie的持久性以及一系列配置,能夠省事很多。
先以面對過程的方式實驗地去編碼:
[注] 若是使用了Fiddler,他會自動爲Web的訪問設置一個代理,這時候若是你關閉了Fiddler可能爬蟲會沒法正常工做,這時候你選擇瀏覽器直連,或者設置爬蟲的代理爲Fiddler便可。
[注2]爬蟲不要頻率太快,不要影響到別人服務器的正常運行,若是不當心IP被封了可使用代理(重要數據不要使用不安全的代理),網上有不少收費/免費的代理,能夠去試下。
過程當中得到的經驗:
在上面第一部分,不知道做用的參數不要亂填,只須要填幾個最重要的就夠了,好比UA,有時候填了不應填的請求將會返回錯誤狀態.,儘可能把可分離的邏輯寫成函數來調用,好比生成的表單參數,加密方法等.
在上面第二部分若是請求失敗能夠配合抓包軟件查看程序和瀏覽器發送的請求有什麼差異,遺漏了什麼重要的地方,儘可能讓程序模仿瀏覽器的必要的行爲。
第三部分中,由於拿到的數據是以下圖1這樣的,因此須要最後輸出後decode,而後再使用正則表達式提取出雙引號中的內容鏈接誒成一個標記語言的形式,再使用Beautifulsoup解析得到須要的數據,如圖2.
中途可能利用的工具備:
官方正則表達式學習網站
HTML格式美化
正則表達式測試
6、爬蟲技術的拓展與提升
經歷了困難重重,終於獲得了想要的數據,對於異步請求,使用JS渲染頁面後才展現數據的網頁,又或是使用JS代碼加密過的網頁,若是花時間去分析JS代碼來解密,簡單的公有的加密方法卻是無所謂,但對於特別難的加密就有點費時費力了,在要保持抓取效率的狀況下可使用能使用Splash框架:
這是一個Javascript渲染服務,它是一個實現了HTTP API的輕量級瀏覽器,Splash是用Python實現的,同時使用Twisted和QT。Twisted(QT)用來讓服務具備異步處理能力,以發揮webkit的併發能力。
就好比像上面返回成績地址的表單參數,格式爲text,而且無規律,有大幾十行,若是要弄明白每一個參數是什麼意思,還不如加載瀏覽器的JS 或 使用瀏覽器自動化測試軟件來獲取HTML了,因此,遇到這種狀況,在那麼大一段字符串中,只能去猜哪些參數是必要的,哪些參數是沒必要要的,好比上面的,我就看出兩個是有關於返回頁面結果的,其他的有可能存在驗證身份的,時間的什麼的。
對於信息的獲取源,若是另外的網站也有一樣的數據而且抓取難度更低,那麼換個網站爬多是個更好的辦法,以及有的網站根據請求頭中的UA會產生不一樣的佈局和處理,好比用手機的UA可能爬取會更加簡單。
7、後記
幾天後我發現了另外一個格式較好的頁面,因而去爬那個網站,結果他是.jsp的,採用以前的方法跳轉幾個302以後就沒有後續了…後來才猜測瞭解到,最後一個302多是由JS腳本跳轉的,而我沒有執行JS腳本的環境,也不清楚他執行的哪一個腳本,傳入了什麼參數,因而各類嘗試和對比,最後發現:正常請求時,每次都多2個Cookie,開始我想,Cookie不是由Session管理不用去插手的嗎?而後我想以正常方式得到該Cookie,請求了N個地址,結果始終得不到想要的Cookie,因而我直接使用Session.cookies.set('COMPANY_ID','10122')添加了兩個Cookie,還真成了…神奇…
固然,過了一段時間後,又不行了,因而仔細觀察,發現每次就JSESSIONID這一個Cookie對結果有影響,傳遞不一樣的值到不一樣的頁面還…雖然我不認同這種猜的,毫無邏輯效率的瞎試。但經歷長時間的測試和猜想,對結果進行總結和整理也是能發現其中規律的。
關於判斷某動做是否是JS,能夠在Internet選項中設置禁止使用JS
關於失敗了驗證的方法,我強烈建議下載fiddler,利用新建視圖,把登陸過程當中全部的圖片,CSS等文件去掉之後放到新視圖中,而後利用程序登陸的過程也放一個視圖當中,若是沒有在響應中找到須要的Cookie,還能夠在視圖中方便的查看各個JS文件,比瀏覽器自帶的F12好用太多了。 以下圖:
總之,通過這段時間的嘗試,我對爬蟲也有了個初步的瞭解,在這方面,也有了本身作法:
抓包請求 —> 模仿請求頭和表單—>若是請求失敗,則仔細對比正常訪問和程序訪問的數據包 —>成功則根據內容結構進行解析—>清清洗數據並展現
本文來源於網絡 若有侵權請聯繫做者刪除