Python爬蟲 | 基于request-bs4的中國(guó)大學(xué)排名定向爬蟲

Python爬蟲


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è)面信息消痛。

最好大學(xué)網(wǎng)

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è)功能是完全合法的勺疼。^ _^

404

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)行一下程序試試看喲~
程序運(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í)交流~(????????)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贤重,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子清焕,更是在濱河造成了極大的恐慌并蝗,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耐朴,死亡現(xiàn)場(chǎng)離奇詭異借卧,居然都是意外死亡盹憎,警方通過(guò)查閱死者的電腦和手機(jī)筛峭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)陪每,“玉大人影晓,你說(shuō)我怎么就攤上這事¢莺蹋” “怎么了挂签?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)盼产。 經(jīng)常有香客問(wèn)我饵婆,道長(zhǎng),這世上最難降的妖魔是什么戏售? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任侨核,我火速辦了婚禮草穆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搓译。我一直安慰自己悲柱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布些己。 她就那樣靜靜地躺著豌鸡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪段标。 梳的紋絲不亂的頭發(fā)上涯冠,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音逼庞,去河邊找鬼功偿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛往堡,可吹牛的內(nèi)容都是我干的械荷。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼虑灰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吨瞎!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起穆咐,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤颤诀,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后对湃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體崖叫,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年拍柒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了心傀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拆讯,死狀恐怖脂男,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情种呐,我是刑警寧澤宰翅,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站爽室,受9級(jí)特大地震影響汁讼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一嘿架、第九天 我趴在偏房一處隱蔽的房頂上張望卜录。 院中可真熱鬧,春花似錦眶明、人聲如沸艰毒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丑瞧。三九已至,卻和暖如春蜀肘,著一層夾襖步出監(jiān)牢的瞬間绊汹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工扮宠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留西乖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓坛增,卻偏偏與公主長(zhǎng)得像获雕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子收捣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容