##通過一個中國大學大學排名爬蟲的示例進行基礎性理解
以軟科中國最好大學排名為分析對象,基于requests庫和bs4庫編寫爬蟲程序,對2015年至2019年間的中國大學排名數據進行爬取:(1)按照排名先后順序輸出不同年份的前10位大學信息,并要求對輸出結果的排版進行優化;訪問的網址:https://www.shanghairanking.cn/rankings/bcur/2021
##網絡爬蟲定義
Python語言的簡潔性和腳本特點非常適合鏈接和網頁處理。
爬蟲首先要做的工作就是獲取網頁,這里就是獲取網頁的源代碼。 源代碼里包含了網頁的部分有用信息,所以只要把源代碼獲取下來,就可以從中提取想要的信息了。 前面講了請求和響應的概念,向網站的服務器發送一個請求,返回的響應體便是網頁源代碼。
##基本的操作步驟
A:通過網絡鏈接獲取網頁的內容
B:對獲得到的網頁內容進行處理
##所涉及到的庫
##最主流的兩個函數庫:requests和beautifulsoup4
##requests庫的使用
該庫是一個簡潔且簡單的處理HTTP請求的第三方庫,最大優點是程序編寫過程更接近正常URL的訪問過程。
##beautifulsoup4庫的使用
使用requests庫獲取HTML頁面并將其轉換成字符串后,需要進一步解析HTML頁面格式,提取有用的信息。
##Robots協議
Robots 排除協議(Robots Exclusion Protocol) 也被稱為爬蟲協議,它是網站管理者表達是否希望爬蟲自動獲取網絡信息意愿的方法。管理者可以在網站根目錄放置一個 robots.txt文件,并在文件中列出哪些鏈接不允許爬蟲爬取。一般搜索引擎的爬蟲會首先捕獲這個文件,并根據文件要求爬取網站內容。Robots排除協議重點約定不希望爬蟲獲取的內容,如果沒有該文件則表示網站內容可以被爬蟲獲得,然而,Robots協議不是命令和強制手段,只是國際互聯網的一種通用道德規范。絕大部分成熟的搜索引擎爬蟲都會遵循這個協議,建議個人也能按照互聯網規范要求合理使用爬蟲技術。
(一般來說,不允許訪問的網址,相應的網址會進行對應的加密操作。)
##代碼示例
"""網絡爬蟲代碼示例"""
import requests
from bs4 import BeautifulSoup
import bs4
#用來獲取網頁html
def getHTMLText(url):try:r = requests.get(url, timeout=30)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept:return ""
#將對應的網頁用python中對應的數據結構進行存儲
def fillUnivList(ulist, html):soup = BeautifulSoup(html, "html.parser")#BeautifulSoup的一個對象for tr in soup.find('tbody').children:if isinstance(tr, bs4.element.Tag):#bs4.element.Tag用來訪問html指定的元素標簽a = tr('a')tds = tr('td')ulist.append([tds[0].text.strip(), a[0].text.strip(), tds[4].text.strip()])#strip()函數用來去除對應的字符#print(ulist)#及逆行格式設置用來設置美觀的打印格式
def printUnivList(ulist, num):tplt = "{0:^5}\t{1:{3}^15}\t{2:^5}"print(tplt.format("排名", "學校名稱", "學校總分", chr(12288)))for i in range(num):u = ulist[i]print(tplt.format(u[0], u[1], u[2], chr(12288)))print("suc" + str(num))
"""由于大學名稱的被a標簽包含,所以我們可以定義一個列表存放a標簽中的內容(與td標簽進行區分開來)
為了視覺方面更加美觀,可采用中文字符的空格填充chr(12288),目的是為了對齊"""def main():uinfo = []url = 'https://www.shanghairanking.cn/rankings/bcur/2021'html = getHTMLText(url)fillUnivList(uinfo, html)printUnivList(uinfo, 10)main()
##代碼的運行結果:
訪問網址的源碼示例:
##網絡爬蟲的一個自我小小誤區
由于部分的網頁的訪問收到服務器的拒絕,因此通過自己制作網頁來進行對應的訪問,但是在這里忽略了一個特別重要的問題,自己所編寫的網頁并沒有受到對應的服務器鏈接,只是一個單純的html文件,因此我們的處理方法改成了訪問html文件,然后利用request庫beautifulsoup4庫進行處理。
(真正的網址需要受到服務器的請求的處理才可以進行解析)
##test.html源文件代碼
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><table border="1" ><caption>大學排名</caption><tr><td>排名</td><td>學校名稱</td><td>省市</td><td>總分</td><td>培養規模</td></tr><tr><td>1</td><td>清華大學</td><td>北京市</td><td>95.9</td><td>37342</td></tr><tr><td>2</td><td>北京大學</td><td>北京市</td><td>82.6</td><td>36317</td></tr><tr><td>3</td><td>浙江大學</td><td>浙江省</td><td>80</td><td>41188</td></tr><tr><td>4</td><td>上海交通大學</td><td>上海市</td><td>78.7</td><td>40417</td></tr><tr><td>5</td><td>復旦大學</td><td>上海市</td><td>70.9</td><td>25519</td></tr><tr><td>6</td><td>南京大學</td><td>江蘇省</td><td>66.1</td><td>20072</td></tr><tr><td>7</td><td>中國科學技術大學</td><td>安徽省</td><td>65.5</td><td>18507</td></tr><tr><td>8</td><td>哈爾冰工業大學</td><td>黑龍江省</td><td>63.5</td><td>25249</td></tr><tr><td>9</td><td>華中科技大學</td><td>湖北省</td><td>62.9</td><td>23503</td></tr><tr><td>10</td><td>中山大學</td><td>廣東省</td><td>62.1</td><td>23837</td></tr></table></body>
</html>
##效果顯示圖
##網頁中顯示的源碼
##以文件形式處理的代碼示例
"""網絡爬蟲"""
import requests
from bs4 import BeautifulSoup
alluniv = []def fillluniv(soup):data = soup.find_all("tr")for tr in data:ltd = tr.find_all("td")if len(ltd) == 0 :continueoneuniv = []for td in ltd :oneuniv.append(td.string)alluniv.append(oneuniv)# print(alluniv)def printUniv(num):print("{:^4}{:^10}{:^5}{:^8}{:^10}".format("排名","學校名稱","省市","總分","培養規模"))for i in range(1,num+1):print("{:^4}{:^10}{:^5}{:^8}{:^10}".format(alluniv[i][0],alluniv[i][1],alluniv[i][2],alluniv[i][3],alluniv[i][4]))
with open("test.html",'r',encoding="utf-8") as file:content = file.read()soup = BeautifulSoup(content,"html.parser")
fillluniv(soup)
printUniv(10)