關於最好大學排名的爬蟲

来源:https://www.cnblogs.com/billged/archive/2017/12/30/8151209.html
-Advertisement-
Play Games

概述 既然決定把視頻上老師講的實戰都自己動手實現一遍,那麼就先把最好大學排名這個實例自己寫一遍。看視頻的時候挺輕鬆的,但是到自己動手的時候才知道不容易,寫這個程式遇到兩個比較棘手的問題,一個是如何從網頁中提取出自己想要的信息,另一個是信息以什麼樣的形式保存並展示出來。其實幾乎所有的爬蟲都會遇到這兩個 ...


概述

既然決定把視頻上老師講的實戰都自己動手實現一遍,那麼就先把最好大學排名這個實例自己寫一遍。看視頻的時候挺輕鬆的,但是到自己動手的時候才知道不容易,寫這個程式遇到兩個比較棘手的問題,一個是如何從網頁中提取出自己想要的信息,另一個是信息以什麼樣的形式保存並展示出來。其實幾乎所有的爬蟲都會遇到這兩個問題吧,希望在以後的練習中能不斷增強對這兩個問題的處理能力。當然,這個實例還有一個重要的作用是增強自己對beautifulsoup庫的理解和運用。

準備工作

打開Chrome瀏覽器,查看要爬取的頁面是否為靜態頁面,如果不是的話以目前的技術是不能對其進行爬取的,畢竟視頻的錄製已經有一段時間了,網頁可能會有所變化。經檢查,幸好網頁還是靜態的,就可以用requests+bs4對其進行爬取。

調試

不能掄起袖子,就在sublime中猛寫代碼,邊寫邊改,其實效率是很低的,因為如果在編輯器中寫代碼調試,發現自己的代碼不能抓取到目標信息,就必須修改代碼並且重新對網頁進行爬取操作,無疑這種人工的重覆勞動是不行的,效率十分低下,畢竟只是個小白,不能一下子就把正確的信息抓取下來。
針對此問題,可以在Python shell中進行調試,這樣就好了許多。在互動式視窗中引入requests和bs4,在shell中進行調試明顯比在命令行中調試好了許多。
調試過程中儘量用瀏覽器的開發者工具對信息進行分析吧,如果用源代碼對其進行分析的話,結構不清晰,不容易分析。

bd4的使用

根據個人的習慣,發現自己最常用的方法應該是find_all()、對子節點的訪問和平行節點向下遍歷了,有時還會遇到對標簽的屬性信息和文本信息的提取。

find_all()

標簽對象的一個方法,主要是用來定位一個標簽或者是一些標簽的位置,返回的是一個列表,列表裡的每個元素是一個tag對象。此方法常和標簽的屬性組合來完成定位,要註意的是,class屬性由於和Python中的關鍵字衝突,所以用class_代替,由於此方法很常用,所以可以不寫,直接加對括弧就可以表示調用了此方法了,十分方便。

子節點遍歷
  • "." 操作符 得到子節點中第一個符合的標簽
  • .contents 返回一個含所有子節點的列表
  • .children 返回一個可迭代對象,內容和.contents是一樣的
tbody.tr.td
<td>1</td>

值得註意的是,空字元串或者是換行符也算是節點,這是一個大坑,要註意一點。

平行節點的向下遍歷
  • .next_sibling 返回一個標簽對象
  • .next_siblings 返回一個可迭代對象
對標簽屬性的訪問
  • 類似於字典式的訪問
  • get()
 tbody['class']
['hidden_zhpm']
tbody.get('class')
['hidden_zhpm']

也許用第二種意思更清晰點吧==

對標簽中文本信息的提取
  • .string
  • .text
  • .get_text()
td.string
'1'
td.text
'1'
td.get_text()
'1'

遇到的問題

  1. 每所學校的標簽基本上一樣的,有些有屬性還能精准定位,而有些沒有屬性,不能精準的定位,而且還有些空格或者是換行符還混進來,增加了提取信息的難度。
  2. 每所學校要獲取的信息有三個:排名、學校名稱和所在地區,應該以哪種方式對它們進行保存也是個問題。
  3. 把獲取到的信息格式化輸出也是個問題,因為要做到簡潔、清晰和美觀。
  • 對於第一個問題,既然有些標簽沒有屬性,不能精確定位,又不能將其放棄,那麼只能不用配合屬性將它們都抓取下來,其中混雜著換行符這個垃圾信息,可以增加一個判斷語句來將換行符給排除掉:
    if isinstance(tr, bs4.element.Tag)
  • 第二個問題,用列表的形式將這三個信息保存下來,而這三個元素是列表的一個元素,也就是嵌套列表,列表可以從主函數這邊傳遞過去。
  • 第三個問題,格式化輸出可以用字元串的format函數,但是還是遇到了問題,主要是大學名稱太長會把後面的省市的一部分空間給占用掉,造成不對齊現象。測試了很多次,在設置的長度足夠長的情況下,只要中文字數超過7個,必將不對齊,很神奇的現象,跑去論壇問,也沒有誰說出個所以然來,很無奈。format函數在一般情況下不會出現問題,先這樣吧。

總結

對於這個爬蟲程式的編寫,最大的收穫就是幫助我理解和掌握beautifulsoup的用法,當然還有其他方面的收穫,比如怎樣將信息格式化輸出和學習老師編寫代碼的方法,雖然最後格式化輸出有點不理想,但整個程式在整體上還是成功的,希望自己繼續努力。

源代碼

from fake_useragent import UserAgent
import requests
from requests import Timeout, HTTPError
from bs4 import BeautifulSoup
import bs4


def get_page(url, ua):      
    try:
        headers = {'User-Agent':ua}
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        response.encoding = 'utf-8'
        return response.text
    except Timeout:
        print('requests timeout')
        get_page(url)
    except HTTPError:
        print('the http error(maybe status is not 200)')
    except:
        print('other error')

def parse_page(html):
    soup = BeautifulSoup(html, 'html.parser')
    return soup 

def get_message(html, ulist):
    tbody = html.find('tbody', class_='hidden_zhpm')
    trs = tbody('tr')
    for tr in trs:
        if isinstance(tr, bs4.element.Tag):
            tds = tr.contents
            ulist.append([tds[2].string.strip(),tds[4].string.strip(), tds[0].string.strip()])

def print_message(messages):
    templet = '{0:<50}\t{1:<50}\t{2:<50}'
    print(templet.format('排名', '學校名稱', '省市'))
    for ult in messages:
        print(templet.format(ult[2], ult[0], ult[1], ' '))

        
def main():
    ua = UserAgent()
    ua = ua.random
    url = 'http://www.zuihaodaxue.com/zuihaodaxuepaiming2016.html'
    html = get_page(url, ua)
    soup = parse_page(html)
    ulist = []
    get_message(soup, ulist)
    print_message(ulist)

main()

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 偶然看見這樣一個案例,先上代碼: public class GenericAdd{ //泛型方法實現兩個數相加 public <T extends Number> double add(T t1, T t2){ double sum = 0.0; sum = t1.doubleValue() + t ...
  • MarkDown筆記 目的 寫這篇文章,一來是記錄一下,以備日後使用;二來是我看到網上很多關於MarkDown的語法總結得不是很全面。 語法 1.標題 標題有兩種表示方式,第一種是Atx,這是我見的最多的;第二種是Setext。下麵分別來介紹一下。 (1)Atx 使用 表示,和HTML的h1~h6標 ...
  • 讓我們先來預覽一下代碼運行效果吧: 首先分析163郵箱登陸頁面的網頁結構(按F12或單擊滑鼠右鍵選擇審查元素) 1、定位到登陸框(註意登錄框是一個iframe,如果不定位到iframe的話是無法找到之後的郵箱地址框和密碼輸入框的) 2、定位到郵箱地址框(name='email') 3、定位到密碼輸入 ...
  • C 語言的 static 關鍵字有三種(具體來說是兩種)用途: 1. 靜態局部變數:用於函數體內部修飾變數,這種變數的生存期長於該函數。 要明白這個用法,我們首先要瞭解c/c++的記憶體分佈,以及static所在的區間。 對於一個完整的程式,在記憶體中的分佈情況如下圖: 1.棧區: 由編譯器自動分配釋放 ...
  • 1排版 1 1相對獨立的程式塊之間、變數說明之後必須加空行。 示例:如下例子不符合規範。 if (!valid_ni(ni)) { ... // program code } repssn_ind = ssn_data[index].repssn_index; repssn_ni = ssn_dat ...
  • 本文主要介紹Spring中, 1 Bean 的 init-method 和 destroy-method 2 集合類型的裝配 3 註解方式裝配 4 以自動掃描把組件納入spring容器中管理 5 代理模式 一、Bean 的 init-method 和 destroy-method 以前在學Servl ...
  • 1.JDK API中RandomAccessFile類的描述 此類的實例支持對隨機訪問文件的讀取和寫入。隨機訪問文件的行為類似存儲在文件系統中的一個大型 byte 數組。存在指向該隱含數組的游標或索引,稱為文件指針;輸入操作從文件指針開始讀取位元組,並隨著對位元組的讀取而前移此文件指針。如果隨機訪問文件 ...
  • 字元流按字元個數輸入、輸出數據。 1.Reader類和FileReader類 Reader類是字元輸入流的超類,FileReader類是讀取字元的便捷類,此處的便捷是相對於其父類(另一個字元輸入流)InputStreamReader而言的。 read()每單字元讀取: read(char[] c)讀 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...