Python3爬蟲(1)--urllib請求庫的基本方法、高級方法、異常處理

2021-02-14 數據運營與數據分析

本文全面講解urllib庫基本使用、高級應用、異常處理,建議收藏!!!

一、urllib庫基本使用

語法:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

注意:data參數,當給這個參數賦值時,HTTP的請求就使用POST方法,如果data=None或者不寫,則使用get方法。1.1、url庫他是python內置的HTTP請求庫

他主要包含4個模塊

request: 最基本的HTTP請求模塊,可以用來模擬發送請求。只需要傳入URL和額外參數,就可以模擬實現這個過程
import urllib.request
url="https://me.csdn.net/column/weixin_41685388"
response = urllib.request.urlopen(url)
print(response.read().decode('utf-8'))  
# read()獲取響應體的內容,內容是bytes字節流,需要轉換成字符串

parse:一個工具模塊提供了很多URL的處理方法,如:拆分、解析、合併、格式轉換等。robotparser:主要用於識別網站的robots.txt文件,判斷哪些連結可以爬。很少使用。1.2、第一個簡單的get請求
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
url="https://me.csdn.net/column/weixin_41685388"
response = urllib.request.urlopen(url)
print(type(response)) #輸出:<class 'http.client.HTTPResponse'>
# 一個HTTPResponse類型的對象,
# 主要包含read()、readinto()、getheader(name)、getheaders()、fileno()等方法,
# 以及msg、version、status、reason、debuglevel、closed等屬性。
 
# 常用status屬性得到返回結果的狀態碼
print(response.status)  #返回200 表示正常請求
 
# getheaders()返回頭部信息
print(response.getheaders())
 
# 返回頭部信息中'Server'的值,伺服器的搭建相關信息
print(response.getheader('Server'))
 
# 常用.read().decode('utf-8')返回網頁內容,read()獲取響應體的內容,內容是bytes字節流,需要轉換成字符串
print(response.read().decode('utf-8'))  #網頁內容

1.3、判斷是get請求和post請求

問題來了,如何判斷是get請求和post請求,谷歌瀏覽器為例:打開網頁-->右擊,檢查(N)-->Network-->F5刷新,找到我們需要的Name,Method的值一看就知道了,注意往往第一次使用的時候檢查功能的時候默認沒有打開Method,需手動勾選一下。

get請求,如:https://blog.csdn.net/weixin_41685388/category_9426224.html連結

如何查看是否是我們需要的Name?

請求時需要的內容:

來一個post請求,看長啥樣如:http://fanyi.youdao.com/

請求時需要的內容:具體看4中代碼 

1.4、post請求表單的提交

在使用urllib.request.urlopen()函數有一個data參數,當給這個參數賦值時,HTTP的請求就使用POST方法,如果data=None或者不寫,則HTTP的請求就使用get方法。data參數的格式必須符合application/x-www-form-urlencoded的格式。需要urllib.parse.urlencode()將字符串轉化為這個格式。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib.request
import urllib.parse
import json
import time
 
def youdao(input):
    #url=r"http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
    # 調試後發現設置了反爬機制,需要將「_o」刪除即可。
    url=r"http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
    #用於隱藏身份,Headers必須是字典,在網頁檢查的Request Headers中,常調用Cookie和User-Agent,
    # 使用urllib.request.Request()才能調用該功能。
    Headers = { } 
    Headers["Cookie"]=r'OUTFOX_SEARCH_USER_ID_NCOO=1564612197.2237918; OUTFOX_SEARCH_USER_ID="1638006579@10.108.160.19"; _ga=GA1.2.269278628.1571982437; _ntes_nnid=db62add68d78e9de1c202b8b131b32a4,1579175684866; JSESSIONID=aaaGcKLB2j8UhdX6Q3V_w; SESSION_FROM_COOKIE=unknown; ___rl__test__cookies=1579203741289'
    Headers["User-Agent"]=r"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
    data = { } #post請求需要的data參數,在網頁檢查的Form Data中,
    #data["i"]="I am jalen" #認真一點你會發現這就是我們輸入的值,自己做一個簡單的有道翻譯只需要修改這裡就可以實現
    data["i"] = input  #那就按照習慣在函數外單獨輸入經常變化的值
    data["from"]="AUTO"
    data["to"]="AUTO"
    data["smartresult"]="dict"
    data["client"]="fanyideskweb"
    data["salt"]="15792037412906"
    data["sign"]="324404ee89ccb63c2ea1efb7d311db26"
    data["ts"]="1579203741290"
    data["bv"]="74b3450c611e373bdb05dc0a4ecdedd0"
    data["doctype"]="json"
    data["version"]="2.1"
    data["keyfrom"]="fanyi.web"
    data["action"]="FY_BY_CLICKBUTTION"
    data = urllib.parse.urlencode(data).encode("utf-8") #post請求的data參數格式轉化
    req =  urllib.request.Request(url,data,Headers)
    response = urllib.request.urlopen(req,timeout=30)
    html = response.read().decode("utf-8")  #返回網頁內容
    # print(type(html),html)  #後面就可以解析了,解析部分在後面的文章中有單獨講解,但這裡還是繼續寫完本例
 
    target = json.loads(html)  #json解析後面的文章會單獨講解
    print("翻譯結果:%s" % (target['translateResult'][0][0]['tgt']))
    # 翻譯結果:我是羅斯
 
if __name__ == '__main__':
    input = "I am jalen"
    time.sleep(5)  #延時提交
    youdao(input)

1.5、隱藏、請求超時、延時提交

在4中得代碼中已經有體現了,簡單的回顧一下:

(1)隱藏:隱藏身份,Headers必須是字典,在網頁檢查的Request Headers中,常調用和修改Cookie和User-Agent,使用urllib.request.Request()才能調用該功能。如:req = urllib.request.Request(url,data,Headers)(2)請求超時:在設定的時間範圍內如果網頁沒有成功請求,則返回錯誤如:response = urllib.request.urlopen(req,timeout=0.3)(3)延時提交:time.sleep(n) ,n表示秒數二、urllib庫高級應用2.1、Handler和Opener簡介

Handler類,可以把他理解為各種處理器,有處理登錄驗證的,有處理cookies的,有處理代理設置的等。

urllib.request模塊裡的 BaseHandler 類,是Handler 的父類 。它提供了如 default_open ()、 protocol_request ()等方法。

各種Handler子類繼承這個BaseHandler類。如:

HTTPDefaultErrorHandler:用於處理HTTPError類型的異常。HTTPRedirectHandler:用於處理重定向。HTTPCookiesProcessor:用於處理cookies。ProxyHandler:用於設置代理,默認代理為空。HTTPpasswordMgr:用於管理密碼,它維護了用戶名和密碼的表。HTTPBasicAuthHandler:用於管理認證,如果一個了解打開時需要認證,那麼可以用它來解決認證問題。其他,查看參考文檔:https://docs.python.org/3/library/urllib.request.html#urllib.request.BaseHandler.

Opener類, 也就是OpenerDirector類  。urlopen()這個方法,就是urllib提供的一個Opener 。Request 和 urlopen( )相當於類庫已經封裝好了常用來做get或post請求的方法,利用它們可以完成基本的請求。實現更高級的功能時,需要深入一層進行個性化配置,使用更底層的實例來完成操作,就用到了 Opener 。通常利用 Handler 來構建 Opener 。Opener 可以使用 open ()方法,返回的類型和 urlopen ()一樣。

案例說明: 

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
from urllib.error import URLError
 
username = 'username'
password = 'password'
url = 'http://localhost:5000/' #DB2默認埠號為:5000;
 
# 1. 構建一個密碼管理對象,用來保存需要處理的用戶名和密碼
p = HTTPPasswordMgrWithDefaultRealm()
# 2. 添加帳戶信息,第一個參數realm是與遠程伺服器相關的域信息,一般沒人管它都是寫None,後面三個參數分別是 Web伺服器、用戶名、密碼
p.add_password(None, url, username, password)
# 3. 構建一個HTTP基礎用戶名/密碼驗證的HTTPBasicAuthHandler處理器對象,參數是創建的密碼管理對象
auth_handler = HTTPBasicAuthHandler(p)
# 4. 通過 build_opener()方法使用這些代理Handler對象,創建自定義opener對象,參數包括構建的 proxy_handler
opener = build_opener(auth_handler)
try:
    result = opener.open(url)
    html = result.read().decode("utf-8")
    print(html)
except URLError as e:
    print(e.reason)
 
'''
這裡首先實例化 HTTPBasicAuthHandler 對象,其參數是 HTTPPasswordMgrWithDefaultRealm 對象,
它利用 add_password ()添加進去用戶名和密碼,這樣就建立了一個處理驗證的 Handler.
接下來,利用這個Handler 並使用 build_opener ()方法構建一個 Opener ,這個 Opener 在發送請求
時就相當於已經驗證成功了 。
接下來,利用 Opener 的 open ()方法打開連結,就可以完成驗證了 。 這裡獲取到的結果就是驗證
'''

2.2、urllib庫免費代理ip的使用
from urllib.error import URLError
from urllib.request import ProxyHandler, build_opener
proxy_handler = ProxyHandler({'http':'http://139.108.123.4:3128','https':'https://157.245.54.87:8080'})
opener = build_opener(proxy_handler)
try:
    response = opener.open('https://www.baidu.com')
    print(response.read().decode('utf-8'))
except URLError as e:
    print(e.reason)

2.3、urllib庫Cookies 的處理
#網站的 Cookies 獲取
import http.cookiejar, urllib.request
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open ('http://www.baidu.com')
for item in cookie:
    print(item.name +'= '+ item.value)
'''
輸出:
BAIDUID= C8BD9A03380D17E0F44167FD4DCE452E:FG=1
BIDUPSID= C8BD9A03380D17E01BB36C142C466E1D
H_PS_PSSID= 1431_21118_30495_26350_30481
PSTM= 157****043
delPer= 0
BDSVRTM= 0
BD_HOME= 0
'''

#Cookies 實際上也是以文本形式保存
import http.cookiejar, urllib.request
filename = 'cookies.txt'
cookie = http.cookiejar.MozillaCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open("http://www.baidu.com")
cookie.save(ignore_discard=True, ignore_expires=True)

#保存成 libwww-perl(LWP)格式的 Cookies 文件
import http.cookiejar, urllib.request
filename = 'cookies.txt'
cookie = http. cookiejar. LWPCookieJar (filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open("http://www.baidu.com")
cookie.save(ignore_discard=True, ignore_expires=True)

#利用cookie
import http.cookiejar, urllib.request
cookie = http.cookiejar.LWPCookieJar( )  #LWPCookie格式
# cookie = http.cookiejar.MozillaCookieJar( ) #MozillaCookie格式
cookie.load(r'cookies.txt',ignore_discard=True,ignore_expires=True)
handler=urllib.request.HTTPCookieProcessor(cookie)
opener=urllib.request.build_opener(handler)
response=opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

三、urllib庫異常處理

urllib的error模塊定義了由request模塊產生的異常。如果出現了問題,request模塊便會拋出error模塊中定義的異常。

#基本用法:
from urllib import request, error 
from urllib.error import  HTTPError ,URLError
try: 
    "代碼塊"
except error.URLError as e: 
    print(e.reason,e.code,e.headers,sep='\n')
except (HTTPError, URLError, socket.timeout, AttributeError,UnicodeEncodeError) as e1:
    return
else:
    print("Request Successfully")

我們打開一個不存在的頁面,照理來說應該會報錯,但是這時我們捕獲了URLError這個異常,運行結果程序沒有直接報錯,而是輸出了指定輸出的內容並跳過執行下一條。在很多請求連結的時候避免程序異常終止,同時異常得到了有效處理,通常我們會記錄下異常的url,異常原因,單獨將結果保存,然後先跳過繼續下面的爬去,最後再進一步處理異常值(不同的異常採取不同的處理方法)。

常見異常:URLError, HTTPError, socket.timeout 等

code:返回HTTP狀態碼,比如404表示網頁不存在,500表示伺服器內部錯。

相關焦點

  • python3爬蟲(2)--requests庫的基本方法、高級方法、異常處理
    前言比urllib更強大的python爬蟲請求庫requests,Cookies、登錄驗證、代理設置等操作都有很好的解決重點講解:基本使用,requests庫高級應用,異常處理一、基本使用1.1、一句話的請求#!
  • Python爬蟲之urllib庫—爬蟲的第一步
    當時的感覺就是:哇,好厲害,短短幾行竟然就可以搞定一個看似很複雜的任務,於是就在想這短短的幾行代碼到底是怎麼實現的呢,如何進行更高級複雜的爬取呢?帶著這個問題我也就開始了urllib庫的學習。首先不得不提一下爬取數據的過程,弄清楚這到底是怎樣一個過程,學習urllib的時候會更方便理解。  其實,爬蟲的過程和瀏覽器瀏覽網頁的過程是一樣的。
  • Python爬蟲 | 0x6 - 請求庫:urllib
    urlib庫是Python內置的一個HTTP請求庫,在Python2中由urllib和urllib2
  • python爬蟲基礎之urllib的使用
    、urllib 和 urllib2的關係在python2中,主要使用urllib和urllib2,而python3對urllib和urllib2進行了重構,拆分成了urllib.request, urllib.parse, urllib.error,urllib.robotparser等幾個子模塊,這樣的架構從邏輯和結構上說更加合理。
  • Python爬蟲常用庫之urllib詳解
    1# 請求頭2headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'}3requests = request.Request
  • python爬蟲-學習urllib和requests使用,模擬請求
    urllib介紹Python內置的HTTP請求庫,安裝好Python就能用,它是最基本的請求庫,用於訪問網絡資源,程序發起請求,獲取響應數據,使用該庫實現。主要有4個模塊urllib.request 請求模塊urllib.error 異常處理模塊,捕獲請求和響應中出現的錯誤urllib.parse url解析模塊,提供url處理方法,拆分合併urllib.robotparser robots.txt解析模塊使用get請求get請求一般是我們在瀏覽器地址直接輸入一個地址,就能能訪問到網頁。
  • python爬蟲之urllib庫
    urllib庫簡介urllib 庫是 Python 中一個最基本的網絡請求庫。可以模擬瀏覽器的行為,向指定的伺服器發 送一個請求,並可以保存伺服器返回的數據。urlopen函數在python3的urllib庫中,所有和網絡請求相關的方法,都被集成到urllib.request模塊下了,該函數的使用格式如下:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath
  • python爬蟲常用庫之urllib詳解
    以下為個人在學習過程中做的筆記總結之爬蟲常用庫urlliburlib庫為python3的HTTP內置請求庫urilib的四個模塊:urllib.request:用於獲取網頁的響應內容urllib.error:異常處理模塊,用於處理異常的模塊urllib.parse:用於解析url
  • Python:爬蟲系列筆記(3) -- urllib庫的高級用法
    , 10)4.使用 HTTP 的 PUT 和 DELETE 方法http協議有六種請求方法,get,head,put,delete,post,options,我們有時候需要用到PUT方式或者DELETE方式請求。
  • Python爬蟲之urllib庫—進階篇
    urllib庫除了一些基礎的用法外,還有很多高級的功能,可以更加靈活的適用在爬蟲應用中,比如,用HTTP的POST請求方法向伺服器提交數據實現用戶登錄
  • Python 爬蟲入門四之 Urllib 庫的高級用法
    使用 HTTP 的 PUT 和 DELETE 方法http 協議有六種請求方法,get,head,put,delete,post,options,我們有時候需要用到 PUT 方式或者 DELETE 方式請求。PUT:這個方法比較少見。HTML 表單也不支持這個。
  • 小白學 Python 爬蟲(11):urllib 基礎使用(一)
    爬蟲(3):前置準備(二)Linux基礎入門小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門小白學 Python 爬蟲(5):前置準備(四)資料庫基礎小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝小白學 Python 爬蟲(7):HTTP 基礎小白學 Python 爬蟲(8):網頁基礎
  • 【Python爬蟲】Urllib的使用(2)
    寫在前面這是第二篇介紹爬蟲基礎知識的文章,之前的文章【Python爬蟲】初識爬蟲(1)主要是讓大家了解爬蟲和爬蟲需要的基礎知識
  • Python:爬蟲系列筆記(2) -- 基本了解及urllib的使用
    1.什麼是爬蟲爬蟲,即網絡爬蟲,大家可以理解為在網絡上爬行的一直蜘蛛,網際網路就比作一張大網,而爬蟲便是在這張網上爬來爬去的蜘蛛咯,如果它遇到資源
  • 詳解 python3 urllib
    本文是爬蟲系列文章的第一篇,主要講解 Python 3 中的 urllib 庫的用法。urllib 是 Python 標準庫中用於網絡請求的庫。該庫有四個模塊,分別是urllib.request,urllib.error,urllib.parse,urllib.robotparser。其中urllib.request,urllib.error兩個庫在爬蟲程序中應用比較頻繁。那我們就開門見山,直接講解這兩個模塊的用法。1  發起請求模擬瀏覽器發起一個 HTTP 請求,我們需要用到 urllib.request 模塊。
  • 06-第一個python爬蟲庫urllib
    ,它包含四個模塊:第一個模塊 request,它是最基本的 HTTP 請求模塊,我們可以用它來模擬發送一請求,就像在瀏覽器裡輸入網址然後敲擊回車一樣,只需要給庫方法傳入 URL 還有額外的參數,就可以模擬實現這個過程了。
  • Python 爬蟲入門三之 Urllib 庫的基本使用
    分析扒網頁的方法那麼我們來分析這兩行代碼,第一行1response = urllib2.urlopen("http://www.baidu.com")首先我們調用的是 urllib2 庫裡面的 urlopen 方法,傳入一個 URL,這個網址是百度首頁,協議是 HTTP 協議,當然你也可以把 HTTP 換做 FTP,FILE
  • 小白學 Python 爬蟲(13):urllib 基礎使用(三)
    爬蟲(2):前置準備(一)基本類庫的安裝小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門小白學 Python 爬蟲(5):前置準備(四)資料庫基礎小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝小白學 Python 爬蟲(7):HTTP
  • python3爬蟲入門:常用網絡爬蟲模塊和技術
    urllib模塊urllib庫是python中自帶的模塊,也是一個最基本的網絡請求庫
  • Python 爬蟲入門五之 URLError 異常處理
    HTTPError 是 URLError 的子類,在你利用 urlopen 方法發出一個請求時,伺服器上都會對應一個應答對象 response,其中它包含一個數字」 狀態碼」。102:繼續處理 由 WebDAV(RFC 2518)擴展的狀態碼,代表處理將被繼續執行。200:請求成功 處理方式:獲得響應的內容,進行處理 201:請求完成,結果是創建了新資源。新創建資源的 URI 可在響應的實體中得到 處理方式:爬蟲中不會遇到 202:請求被接受,但處理尚未完成 處理方式:阻塞等待 204:伺服器端已經實現了請求,但是沒有返回新的信 息。