Python爬蟲1.1 — urllib基礎用法教程

綜述

本系列文檔用於對Python爬蟲技術進行簡單的教程講解,鞏固自己技術知識的同時,萬一一不小心又正好對你有用那就更好了。
Python 版本是3.7.4

urllib庫介紹

它是 Python 內置的HTTP請求庫,也就是說我們不需要額外安裝即可使用,它包含四個模塊(主要對前三個模塊進行學習):

  • request : 它是最基本的 HTTP 請求模塊,我們可以用它來模擬發送一請求,就像在瀏覽器裏輸入網址然後敲擊回車一樣,只需要給庫方法傳入 URL 還有額外的參數,就可以模擬實現這個過程了。
  • error : 異常處理模塊,如果出現請求錯誤,我們可以捕獲這些異常,然後進行重試或其他操作保證程序不會意外終止。
  • parse : 用於解析URL,提供了許多URL處理方法,比如拆分、解析、合併等等的方法,以及對參數的拼接等待。
  • robotparser : 主要是用來識別網站的robots.txt協議文件,然後判斷網站的那些數據可以爬,哪些數據不可以爬的,其實用的比較少。

urllib.request 介紹

urlopen()

  1. 參數說明(僅寫了四個最常用的參數)

    • url : 爬取目標的URL;
    • data : 請求參數,如果設置該參數,則請求默認爲post請求;沒有默認爲get請求;
    • timeout : 用於設置超時時間,單位爲秒;
    • context : 必須是一個ssl.SSLContext類型,用來指定SSL設置,忽略未認證的CA證書;
  2. 具體用法

    • GET 請求方式
        # 導入urllib庫
        import urllib.request
        
        # 向指定的url發送請求,並返回服務器響應的類文件對象
        url = "http://www.baidu.com"
        response = urllib.request.urlopen(url=url)
        print(type(response))
        
        # 類文件對象支持文件對象的操作方法,如read()方法讀取文件全部內容,返回字符串
        html = response.read()
        # html = response.readline() # 讀取一行
        # html = response.readlines() # 讀取多行,返回列表
        # 打印響應結果(byte類型)
        print(html)
        # 打印響應結果(utf-8類型)
        # 二進制和字符串之間的相互轉碼使用 encode() 和 decode() 函數
        # encode() 和 decode() 可帶參數,不寫默認utf-8,其他不再特別說明
        print(html.decode())
        # 打印狀態碼
        # print(response.get_code())
        print(response.status)
        # 獲取響應頭
        print(response.getheaders())
        # 獲取響應頭Server信息
        print(response.getheader('Server'))
        # 獲取響應結果原因
        print(response.reason)
    
    • POST 請求方式
        # 導入urllib庫
        import urllib.parse
        import urllib.request
        
        # 向指定的url發送請求,並返回
        post_url = 'https://fanyi.baidu.com/sug'
        # 傳入參數
        form_data = {
            'kw': 'honey'
        }
        # 格式化參數
        form_data = urllib.parse.urlencode(form_data).encode()
        
        response = urllib.request.urlopen(url=post_url, data=form_data)
        # 打印服務器響應的類文件對象
        print(type(response))
        
        # 類文件對象支持文件對象的操作方法,如read()方法讀取文件全部內容,返回字符串
        html = response.read()
        # 打印響應結果(byte類型)
        print(html)
        # 打印響應結果(utf-8類型)
        print(html.decode())
        # 打印狀態碼
        print(response.status)
        # print(response.getcode())
        # 獲取響應頭
        print(response.getheaders())
        # 獲取響應頭Server信息
        print(response.getheader('Server'))
        # 獲取響應結果原因
        print(response.reason)
    

urlretrleve()

  1. 參數說明

    • url : 下載鏈接地址;
    • filename : 指定保存本地路徑(如果參數未指定,urllib會生成一個臨時文件保存數據);
    • reporthook : 是一個回調函數,當連接上服務器、以及相應的數據塊傳輸完畢時會觸發該回調,我們可以利用這個回調函數來顯示當前的下載進度;
    • data : 指post導服務器的數據,該方法返回一個包含兩個元素的(filename, headers) 元組,filename 表示保存到本地的路徑,header表示服務器的響應頭;
  2. 具體用法

        # 引入所需要的庫
        import os
        import urllib.request
        
        
        # 定義回調函數
        def call_back(a, b, c):
            """
            圖片下載回調
            :param a: 已經下載的數據塊
            :param b: 數據塊的大小
            :param c: 遠程文件的大小
            :return: 
            """
            per = 100.0 * a * b / c
            if per > 100:
                per = 100
            print('%.2f%%' % per)
        
        
        # 定義下下載的地址
        url = 'http://www.baidu.com'
        # 構造文件保存路徑
        path = os.path.abspath('.')
        file_path = os.path.join(path, 'baidu.html')
        # 進行下載
        urllib.request.urlretrieve(url, file_path, call_back)
    
    

urllib.parse 介紹

urlencode()

  1. 參數說明

    • query : url參數,可以是字符串,也可以是字典;
    • encoding : 編碼方式;
  2. 具體用法

        # 引入所需要的庫
        import urllib.parse
        # 參數數據
        data = {
            'name': '張三',
            'age': 26
        }
        # 進行編碼
        ret = urllib.parse.urlencode(data)
        print(ret)
    

parse_s()

  1. 參數說明

    • qs : url參數,編碼後的字符串;
    • encoding : 字符方式;
  2. 具體用法

        # 引入所需要的庫
        import urllib.parse
        # 參數數據
        data = {
            'name': '張三',
            'age': 26
        }
        # 進行編碼
        ret1 = urllib.parse.urlencode(data)
        print(ret1)
        # 進行解碼
        ret2 = urllib.parse.parse_qs(ret1)
        print(ret2)
    

urlparse()

  1. 參數說明

    • url : url地址字符串;
  2. 具體用法

        # 引入所需要的庫
        import urllib.parse
        # 聲明url
        url = "https://www.baidu.com/s?wd=urlparse&rsv_spt=1&rsv_iqid=0x921f00fe005646ef&issp=1&f=8"
        # 進行url解析
        ret = urllib.parse.urlparse(url)
        print(ret)
        print('scheme:', ret.scheme)  # 協議
        print('netloc:', ret.netloc)  # 域名服務器
        print('path:', ret.path)  # 相對路徑
        print('params:', ret.params)  # 路徑端參數
        print('fragment:', ret.fragment)  # 片段
        print('query:', ret.query)  # 查詢
        
        # urlunparse() 與 urlparse() 對應相反函數
        # 使用urlparse的格式組合成一個url,可以直接將urlparse的返回傳遞組合
        ret1 = urllib.parse.urlunparse(ret)
        print(ret1)
    

urlsplit()

  1. 參數說明

    • url : url地址字符串;
  2. 具體用法

        # 引入所需要的庫
        import urllib.parse
        # 聲明url
        url = "https://www.baidu.com/s?wd=urlparse&rsv_spt=1&rsv_iqid=0x921f00fe005646ef&issp=1&f=8"
        # 進行url解析
        ret = urllib.parse.urlsplit(url)
        print(ret)
        print('scheme:', ret.scheme)  # 協議
        print('netloc:', ret.netloc)  # 域名服務器
        print('path:', ret.path)  # 相對路徑
        print('fragment:', ret.fragment)  # 片段
        print('query:', ret.query)  # 查詢
        
        # urlunsplit() 與 urlsplit() 對應相反函數
        # 使用urlsplit的格式組合成一個url,可以直接將urlsplit的返回傳遞組合
        ret1 = urllib.parse.urlunsplit(ret)
        print(ret1)
        
        # 此函數和urlparse函數的區別在於此函數沒有params
    

urljoin()

  1. 參數說明

    • qs : url參數,編碼後的字符串;
    • encoding : 字符方式;
  2. 具體用法

        # 引入所需要的庫
        import urllib.parse
        
        # 聲明url
        url = "https://www.baidu.com/"
        # 參數數據
        data = {
            'name': '張三',
            'age': 26
        }
        # 格式化參數
        data = urllib.parse.urlencode(data)
        # 進行url拼接
        ret = urllib.parse.urljoin(url, data)
        print(ret)
    

urllib.error 介紹

我們在爬蟲的時候發請求的時候難免出現錯誤,如訪問不到服務器或者訪問被禁止等等,error分爲URLError和HTTPError兩類:

  1. URLError

    • 沒有網
    • 服務器鏈接失敗
    • 找不大指定服務器
  2. HTTPError

    • 是URLError的子類
  3. 兩者區別和聯繫

    • URLError封裝的錯誤信息一般是由網絡引起的,包括url錯誤
    • HTTPError封裝的錯誤信息一般是服務器返回了錯誤狀態碼
    • URLError是OSERROR的子類,HTTPError是URLError的子類
    • 【注意】兩個同時捕獲的時候需要將子類放在上面,父類放在下面
  4. 用法

        # 引入所需要的庫
        import urllib.error
        import urllib.request
        
        # 一個訪問異常的url
        url = 'https://www.mz.com/156427/100'
        # 捕獲異常
        try:
            ret = urllib.request.urlopen(url)
            print(ret)
        except urllib.error.HTTPError as e:
            print(e.getcode())
        except urllib.error.URLError as e:
            print(e)
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章