- 功能描述
- 舉例說明
- 設計方法
- 程序結構的設計步驟
- 初步完整代碼及注釋
- 實例優化的代碼及步驟
功能說明
輸入:大學排名URL鏈接
輸出:大學排名信息的屏幕輸出(排名、大學名稱、總分)
技術路線:requests + bs4
定向爬蟲:僅對輸入URL進行爬取,不擴展爬取
確定可行性????
提取返回的頁面是否出現在HTML的代碼中
舉例- 例如最好大學網
http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html
查看源代碼
查一個例子:Ctrl+F搜索----清華大學
查看網站是否提供robots協議?????
可以手工查看robots協議,發現不存在,則在這里使用爬蟲是完全合法可以實現的
希望爬取出來的樣例是 排名 學校名稱 總分
獲取大學排名並且輸出大學信息可以分為以下三個步驟
設計方法
- 一、從網頁上獲取大學排名網頁內容
- 二、提取網頁內容中信息到合適的數據結構
- 三、利用數據結構展示並 輸出結果
程序結構的設計步驟:
- 步驟一、從網絡上獲取大學排名的網頁內容getHTMLText()
- 步驟二、提取網頁內容中信息到合適的數據結構 fillUnivList()
- 步驟三、利用數據結構展示並輸出結果printUnivList()使用這三個模塊是結果更加清晰可讀。
完整代碼及注釋
1 import requests #首先引入requests庫和BeautifulSoup庫 2 from bs4 import BeautifulSoup 3 import bs4 4 5 #定義三個函數分別對應三個步驟,將三個函數寫進來import requests 6 #首先定義三個函數,然后分別定義他們的接口 7 def getHTMLText(url): #輸入獲取的url信息,輸出是url的內容 8 try: 9 r = requests.get(url,timeout = 30)#get獲取url信息,並且設置時間是30秒 10 r.raise_for_status() #用raise_for_status產生異常信息 11 r.encoding = r.apparent_encoding #修改編碼 12 return r.text #將網頁的內容返回給程序的其他部分 13 except: 14 return "" #出現錯誤,則返回空字符串 15 16 def fillUnivList(ulist,html): #將一個HTML頁面中的關鍵數據添放到list列表中(最核心的部分),要使用BeautifulSoup庫 17 soup = BeautifulSoup(html,"html.parser") #用BeautifulSoup類來“煲湯”,采用html的解析器 18 #觀察要爬取的網頁源代碼,發現所有的大學信息被封裝在一個表格中,表格的標簽叫 tbody, 19 # 在tbody中,每個大學的信息又被封裝在一個標簽中,這個標簽叫tr,即每一個tr標簽包含了所有大學的信息 20 #每個tr標簽的信息又被td包圍 21 #所以要在整個HTML中,首先找到tbody標簽,獲取所有大學的相關信息 ;然后在tbody標簽中解析tr標簽,獲得每一個大學信息;再把tr標簽的td標簽找到,把每一個大學的相關參數寫到ulist 列表中(用遍歷以及查找方法獲得) 22 for tr in soup.find('tbody').children: #for語句查找tbody標簽,並且將孩子children遍歷 23 if isinstance(tr,bs4.element.Tag): #isinstance對函數進行判斷,檢測tr標簽的類型,如果tr不是bs4定義的Tag類型,將過濾掉(並且為了代碼可以運行需要引入一個新的類型bs4) 24 tds = tr('td') #將所有的td 標簽存為一個列表類型tds , 25 ulist.append([tds[0].string,tds[1].string,tds[3].string]) #在ulist中增加對應的字段,分別是大學排名、大學名稱、大學評分 26 '''pass首先解析HTML代碼中tbody標簽所在的位置,在tbody標簽中找到每一所大學對應上午tr 標簽,在tr 標簽中找到td標簽的信息,並把需要的td 標簽添加到列表中, 27 ''' 28 '''下面是實現打印大學列表的相關功能 29 需要用到格式化輸出《格式化輸出的方法》 30 ''' 31 def printUnivList(ulist,num): #將ulist信息打印出來 32 print("{:^10}\t{:^6}\t{:^10}".format("排名","學校名稱","總分"))#print 函數實現對表頭的打印,下面實現對其他信息的打印 33 for i in range(num): 34 u = ulist [i] 35 '''所有的信息保存在ulist中,想要輸出的學校數量由num控制用for循環實現''' 36 print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2])) 37 #將第i個學校的信息,作為一個簡單的變量u來代替,然后將每一所學校的信息打印出來 38 #注意:為了保證輸出的效果,需要使用和表頭相一致的支付串表示 39 # print("Suc"+str(num)) #num表示到打印出來的學校的個數 40 # #定義好三個函數之后要寫主函數,主函數約定使用main 41 42 43 def main(): 44 uinfo=[] 45 url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html" 46 html = getHTMLText(url) 47 fillUnivList(uinfo,html) 48 printUnivList(uinfo,20) #打印大學信息,20個學校(univs) 49 50 mai
同上。
1 import requests 2 from bs4 import BeautifulSoup 3 import bs4 4 5 def getHTMLText(url): 6 try: 7 r = requests.get(url, timeout=30) 8 r.raise_for_status() 9 r.encoding = r.apparent_encoding 10 return r.text 11 except: 12 return "" 13 14 def fillUnivList(ulist, html): 15 soup = BeautifulSoup(html, "html.parser") 16 for tr in soup.find('tbody').children: 17 if isinstance(tr, bs4.element.Tag): 18 tds = tr('td') 19 ulist.append([tds[0].string, tds[1].string, tds[3].string]) 20 21 def printUnivList(ulist, num): 22 print("{:^10}\t{:^6}\t{:^10}".format("排名","學校名稱","總分")) 23 for i in range(num): 24 u=ulist[i] 25 print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2])) 26 27 def main(): 28 uinfo = [] 29 url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' 30 html = getHTMLText(url) 31 fillUnivList(uinfo, html) 32 printUnivList(uinfo, 20) # 20 univs 33 main()
結果
實例優化
對齊效果不好,進行改正優化
中文對齊問題的解決:
采用中文字符的空格填充 chr(12288)
1 def printUnivList(ulist, num): 2 tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" 3 print(tplt.format("排名", "學校名稱", "總分", chr(12288))) 4 for i in range(num): 5 u = ulist[i] 6 print(tplt.format(u[0], u[1], u[2], chr(12288)))
改正后
完整代碼
1 import requests 2 from bs4 import BeautifulSoup 3 import bs4 4 5 def getHTMLText(url): 6 try: 7 r = requests.get(url, timeout=30) 8 r.raise_for_status() 9 r.encoding = r.apparent_encoding 10 return r.text 11 except: 12 return "" 13 14 def fillUnivList(ulist, html): 15 soup = BeautifulSoup(html, "html.parser") 16 for tr in soup.find('tbody').children: 17 if isinstance(tr, bs4.element.Tag): 18 tds = tr('td') 19 ulist.append([tds[0].string, tds[1].string, tds[3].string]) 20 21 def printUnivList(ulist, num): 22 tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" 23 print(tplt.format("排名","學校名稱","總分",chr(12288))) 24 for i in range(num): 25 u=ulist[i] 26 print(tplt.format(u[0],u[1],u[2],chr(12288))) 27 28 def main(): 29 uinfo = [] 30 url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' 31 html = getHTMLText(url) 32 fillUnivList(uinfo, html) 33 printUnivList(uinfo, 20) # 20 univs 34 main()