說好的要從練習中學習爬蟲的基礎操作,所以就先從容易爬取的靜態網頁開始吧!
今天要爬取的是最好大學網上的2018年中國大學排名。我個人認為這個是剛接觸爬蟲時用來練習的一個很不錯的網頁了。
在說這個練習之前,給新着手學習爬蟲的同學提供一個中國MOOC上北京理工大學嵩天老師的視頻,
Python網絡爬蟲與信息提取
今天這個練習便是出自嵩天老師的視頻
運行平台:Windows
Python版本:Python3.6
IDE: Sublime Text Python自帶IDLE
其他:Chrome瀏覽器
簡述流程為:
步驟1:利用IDLE簡單測試爬取的網頁
步驟2:瀏覽器上查看網頁信息
步驟3:從網頁中獲取HTML文本
步驟4:提取網頁信息並存入合適的數據結構
步驟5:利用數據結構輸出結果
首先我們可以用Python自帶的IDLE來簡單測試一下網頁是否可訪問

我們通過requests的get方法已經獲得了網頁的響應,通過返回的狀態碼200可以知道訪問成功,隨后用text方法來查看返回的HTML文檔,這里要注意記得控制返回的Text文檔大小,用切片的方法控制一下,否則很容易使得IDLE無響應。我們注意到返回的源碼中有許多亂碼,這是怎么回事呢?我們先查看一下網頁的編碼是什么,返回的‘ISO-8859-1’可以讓我們知道該編碼不支持中文顯示,所以我們可以通過修改編碼為‘utf-8’的方法成功取得可以顯示中文的源碼。當然我們還可以用robotparser模塊查看網頁的obots.txt文件,robots.txt文件是網頁用來告訴我們哪些頁面允許爬取,哪些頁面不建議爬取,這並不是一個強制性約束的文件,不過在涉及到其他應用的時候,還是建議遵守文件。當然,我們這里只是用來練習,是沒啥問題的,需要查看最好大學網的robots。txt文件也可以直接輸入網址“
http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html/robots.txt”,當然,你會看到404 Not Found,這表示這個網頁沒有robots.txt,相應的也就是默認可以爬取的,當然,爬取的時候需要控制好頻率。
隨后,我們打開Chrome瀏覽器,打開網頁。

可以看到排名都在一個總的表格中,我們要爬取的學校以及總分排名等信息也都在其中。我們可以在清華大學點擊鼠標右鍵,然后點擊檢查,看看網頁返回了什么。

可以在下方看到(也有可能出現在右方,這個可以自己設置,下方這個新出的區域的右上角有三個豎着的點,點擊就可以設置了)清華大學,北京,95.3等大學信息都在標簽<tbody>的子標簽<tr>的<td>里。清楚了我們要爬取的信息位置后,接下來就是寫代碼獲取這些信息了。


第一步就是使用嵩天老師一直強調的通用代碼框架了,這個框架可以用在很多爬蟲中用來獲取HTML文本,並且它通過response.raise_for_status()方法判斷返回的狀態碼是不是200,如果不是,就會引發HTTPError異常,然后通過try except的異常處理獲取到異常,而apparent_encoding則可以使得返回的編碼准確。這樣一個簡單的通用代碼框架可以有效的處理訪問處理時遇到的網絡問題。

第二步則是用BeautifulSoup解析提取到的HTML文本,'html.parser'是Python標准庫作為解析器,剛才用瀏覽器已經看到我們所要提取的信息位置位於標簽<td>里,所以用for循環獲取找到<tbody>的所有孩子節點,然后用isinstance方法剔除一些不需要的信息,然后將tr中的td內容合成一個列表,最后將信息存入列表ulist中。


第三步則是將存入列表中的信息格式化輸出出來,這一步也可以用文件操作替換,后續很多練習會用到文件存放。這里還是使用format格式化輸出的辦法。首先來理解一下tplt這個字符串的結構,如圖所示:


關於format的其他用法,比如填充對齊,精度控制等大家有興趣可以百度一下啦。關於chr(12288)則是嵩天老師在優化中文對齊時提到的,因為中文字符對齊與英文字符對齊的寬度不一樣,所以用chr(12288)使得采用中文字符的空格對齊。
然后就是使用format輸出列表中的文本了。這里還用到了range 來控制輸出的大學數。
最后我們看下輸出結果,這里只輸出了排名前20的大學。


源碼的話,由於代碼不長,就直接文本放出來吧
''' 利用requests+BeautifulSoup爬取最好大學網中2018年中國大學排名 ''' import requests from bs4 import BeautifulSoup import bs4 def get_one_page(url): try: response = requests.get(url,timeout=30) response.raise_for_status() response.encoding = response.apparent_encoding return response.text except: print("產生異常") return "" def parse_one_page(ulist,html): soup = BeautifulSoup(html,'html.parser') for tr in soup.find('tbody').children: if isinstance(tr,bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string,tds[1].string,tds[2].string,tds[3].string]) def print_one_page(ulist,num): tplt = "{0:^10}\t{1:{4}^10}\t{2:{4}^10}\t{3:^10}" print(tplt.format("排名","學校名稱","學校地址","總分",chr(12288))) for i in range(num): u = ulist[i] print(tplt.format(u[0],u[1],u[2],u[3],chr(12288))) def main(): uinfo = [] url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html' html = get_one_page(url) parse_one_page(uinfo,html) print_one_page(uinfo,20) if __name__ == '__main__': main()
好啦,今天的練習就到此結束了,應該寫得還是挺詳細的吧(emmmmm)。希望大家能夠有所收獲咯,當然,大神還是繞路吧,小白瑟瑟發抖。如果有錯誤的地方,請大家多多指教。