Python版本:Python3.5 预愤;
技術(shù)路線:requests-bs4 县好。
功能描述:
俗話說(shuō)“有人的地方就有江湖”构哺,那么有大學(xué)的地方就有排名捡絮。2018年大學(xué)排名是怎樣的呢熬芜?最好大學(xué)網(wǎng)上提供了2018年的中國(guó)大學(xué)排名榜莲镣。
鏈接:http://www.zuihaodaxue.com/zuihaodaxuepaiming2018.html
我們要一個(gè)程序福稳,它能夠通過(guò)鏈接爬取大學(xué)排名,并將大學(xué)排名信息屏幕輸出瑞侮。所以的圆,功能需求如下:
- 輸入:大學(xué)排名URL鏈接
- 輸出:大學(xué)排名信息的屏幕輸出(排名,大學(xué)名稱半火,總分)
可行性分析:
首先越妈,我們要確定需要的信息是不是寫在HTML頁(yè)面的代碼中。如果是通過(guò)JavaScript等腳本語(yǔ)言生成的钮糖,用requests和BeautifulSoup庫(kù)是無(wú)法獲取它的信息的梅掠。其次,還有網(wǎng)站robots協(xié)議里是否有相關(guān)約定店归。
- 代碼寫是否寫在了HTML頁(yè)面
- robots協(xié)議
1.打開瀏覽器阎抒,輸入我們要訪問(wèn)的網(wǎng)站,我們看到有中國(guó)大學(xué)排名的頁(yè)面信息消痛。
2.點(diǎn)擊右鍵且叁,查看源代碼≈壬。可以看到每個(gè)大學(xué)相關(guān)信息對(duì)應(yīng)的代碼部分逞带,這塊代碼是通過(guò)<tr>標(biāo)簽來(lái)索引的欺矫,且里面索引參數(shù)都寫在了HTML頁(yè)面信息中。因此這個(gè)定向爬蟲是可以設(shè)計(jì)和實(shí)現(xiàn)的展氓。
3.此外穆趴,還有看一下這個(gè)定向爬蟲網(wǎng)站是否提供了robots協(xié)議的約定。打開http://www.zuihaodaxue.com/robots.txt遇汞,看到404 Not Found網(wǎng)頁(yè)不存在毡代,說(shuō)明這網(wǎng)站并沒(méi)有通過(guò)robots協(xié)議對(duì)爬蟲做相關(guān)限制。因此我們爬取大學(xué)排名這個(gè)功能是完全合法的勺疼。^ _^
4.綜合以上:可行性O(shè)K
程序的結(jié)構(gòu)設(shè)計(jì):
- 步驟1:從網(wǎng)絡(luò)上獲取大學(xué)排名網(wǎng)頁(yè)內(nèi)容教寂,定義函數(shù):
getHTMLText()
- 步驟2:提取網(wǎng)頁(yè)中信息并放到合適的數(shù)據(jù)結(jié)構(gòu)定義函數(shù):
fillUnivList()
- 步驟3:利用數(shù)據(jù)結(jié)構(gòu)展示并輸出結(jié)果,定義函數(shù):
printUnivList()
有了這三個(gè)函數(shù)执庐,我們可以把程序封裝成這三個(gè)模塊酪耕,可讀性更好。
代碼編寫:
1.首先轨淌,由于這里邊實(shí)現(xiàn)了網(wǎng)絡(luò)訪問(wèn)請(qǐng)求迂烁,所以我們要 import requests庫(kù) 和 BeautifulSoup庫(kù)。
import requests
from bs4 import BeautifulSoup
2.根據(jù)前面定義的三個(gè)函數(shù)編寫代碼递鹉。由于這個(gè)時(shí)候盟步,我們還沒(méi)有對(duì)函數(shù)內(nèi)部功能進(jìn)行設(shè)計(jì)和實(shí)現(xiàn),所以我們只需要寫出函數(shù)的定義就可以躏结。還有別忘了對(duì)接口的定義却盘。
def getHTMLText(url):
# 輸入是URL信息,輸出是對(duì)應(yīng)HTML的內(nèi)容
retunrn ""
def fillUnivList(ulist, html):
# 將HTML頁(yè)面放到一個(gè)列表(ulist)中
pass
def printUnivList(ulist, num):
# 將ulist信息打印出來(lái)媳拴,num表示打印元素的數(shù)量
print("Suc" + str(num))
def main():
uinfo = []
# 大學(xué)信息所放置的列表
url = http://www.zuihaodaxue.com/zuihaodaxuepaiming2018.html
html = getHTMLText(url)
# 調(diào)用函數(shù)黄橘,將url轉(zhuǎn)化成html
fillUnivList(uinfo, html)
# 將html信息提取后放在uinfo變量中
printUnivList(uinfo, 20)
# 打印前20所大學(xué)信息
main()
3.寫了上面代碼后,整個(gè)mian函數(shù)和結(jié)構(gòu)框架已經(jīng)很清晰了屈溉,但還僅僅是個(gè)半成品塞关,所以要進(jìn)一步填寫三個(gè)函數(shù)的功能~
- 第一個(gè)函數(shù)
getHTMLText(url)
,需要 requests庫(kù) 返回頁(yè)面信息子巾,這里我們可以用通用代碼框架帆赢,如下:
def getHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
# 如果爬取失敗,產(chǎn)生異常信息
r.encoding = r.apparent_encoding
# 使用apparent_encoding修改編碼
return r.text
# 將網(wǎng)頁(yè)的信息內(nèi)容返回
except requests.HTTPError:
return ""
# 若出現(xiàn)錯(cuò)誤线梗,返回空字符串
- 第二個(gè)函數(shù)
fillUnivList(ulist, html)
椰于,程序的核心部分,需要 BeautifulSoup庫(kù) 解析頁(yè)面缠导,中間使用isinstance()
函數(shù)需要調(diào)用 bs4庫(kù) 廉羔。- 所有除了之前的以外,還需
import bs4
- 所有除了之前的以外,還需
import bs4
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, "html.parser")
# 用BeautifulSoup類煲這鍋靚湯,使用html解析器
for tr in soup.find("tbody").children:
# 這步驟需要觀察網(wǎng)頁(yè)源代碼憋他,解析html中的<tbody>
if isinstance(tr, bs4.element.Tag):
# 在<tbody>中找的對(duì)應(yīng)的<tr>
# 檢測(cè)<tr>類型孩饼,若不是bs4庫(kù)定義的Tag類型,將被過(guò)濾 (import bs4)
tds = tr("td")
# 找到<tr>中的<td>,并將其存儲(chǔ)在列表tds中
ulist.append([tds[0].string, tds[1].string, tds[2].string])
# 增加對(duì)應(yīng)字段到列表ulist
- 第三個(gè)函數(shù)
printUnivList(ulist, num)
竹挡,使用 format()方法 格式化輸出镀娶。這里要啰嗦一句:使用format()方法輸出時(shí),定義了槽的大小且輸出內(nèi)容包含中文字符揪罕,當(dāng)中文字符不夠槽的寬帶時(shí)梯码,將默認(rèn)西文字符填充,但是中文和西文字符對(duì)空間的占用又不一樣...- 這意味著什么呢好啰?意味著我們輸出的格式很難對(duì)齊轩娶,灰常不美觀...
- 所以我們要用中文空格符填充~
- utf-8編碼對(duì)應(yīng)中文空格字符為:12288,so框往,填充的字符就是chr(12288)啦~
def printUnivList(ulist, num):
tplt = "{0:^10}\t{1:{3}^12}\t{2:^10}"
print(tplt.format("排名", "學(xué)校名稱", "總分", chr(12288)))
# 先打印表頭
for i in range(num):
u = ulist[i]
print(tplt.format(u[0], u[1], u[2], chr(12288)))
# 打印每一所學(xué)校的信息
- 至此鳄抒,所有的代碼都寫完啦,我們已經(jīng)成功寫完了定向爬蟲了椰弊,好激動(dòng)有木有许溅?趕緊運(yùn)行一下程序試試看喲~
最終代碼:
# 實(shí)踐:中國(guó)大學(xué)排名定向爬取
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except requests.HTTPError:
return ""
def fillUnivList(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])
def printUnivList(ulist, num):
tplt = "{0:^10}\t{1:{3}^12}\t{2:^10}"
print(tplt.format("排名", "學(xué)校名稱", "總分", chr(12288)))
for i in range(num):
u = ulist[i]
print(tplt.format(u[0], u[1], u[2], chr(12288)))
def main():
uinfo = []
url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2018.html"
html = getHTMLText(url)
fillUnivList(uinfo, html)
printUnivList(uinfo, 20)
main()
1.本帖僅作為學(xué)習(xí)筆記;
2.有錯(cuò)誤之處歡迎指出秉版;
3.也歡迎大家一起學(xué)習(xí)交流~(????????)