python爬蟲基礎02-urllib庫

Python網絡請求urllib和urllib3詳解

urllib是Python中請求url鏈接的官方標準庫,在Python2中主要爲urllib和urllib2,在Python3中整合成了urllib。html

官方文檔連接爲:https://docs.python.org/3/library/urllib.htmlpython

而urllib3則是增長了鏈接池等功能,二者互相都有補充的部分。瀏覽器

urllib

它是 Python 內置的 HTTP 請求庫,也就是說咱們不須要額外安裝便可使用,基本上涵蓋了基礎的網絡請求功能,它包含四個模塊:安全

  • urllib.request 用於打開和讀取url服務器

  • urllib.error 用於處理前面request引發的異常cookie

  • urllib.parse 用於解析url網絡

  • urllib.robotparser 用於解析robots.txt文件post

urllib.request

urllib中,request這個模塊主要負責構造和發起網絡請求,並在其中加入Headers、Proxy等。網站

利用它能夠模擬瀏覽器的一個請求發起過程ui

發起GET請求

主要使用urlopen()方法來發起請求:

from urllib import request

resp = request.urlopen('http://www.baidu.com')
print(resp.read().decode())

urlopen()方法中傳入字符串格式的url地址,則此方法會訪問目標網址,而後返回訪問的結果。

訪問的結果會是一個http.client.HTTPResponse對象,使用此對象的read()方法,則能夠獲取訪問網頁得到的數據。可是要注意的是,得到的數據會是bytes的二進制格式,因此須要decode()一下,轉換成字符串格式。

發起POST請求

urlopen()默認的訪問方式是GET,當在urlopen()方法中傳入data參數時,則會發起POST請求。

注意:傳遞的data數據須要爲bytes格式。

用 urllib.parse 模塊裏的 urlencode() 方法來將參數字典轉化爲字符串。第二個參數指定編碼格式,在這裏指定爲 utf8。

設置timeout參數還能夠設置超時時間,若是請求時間超出,那麼就會拋出異常。

from urllib import request

resp = request.urlopen('http://httpbin.org/post', data=b'word=hello')
print(resp.read().decode())

設置超時

設置超時時間,單位爲秒,若是請求時間超出尚未獲得響應,那麼就會拋出URLError 異常

from urllib import request

response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)

 

Request對象

如上所示,urlopen()方法能夠實現最基本請求,但這幾個簡單的參數並不足以構建一個完整的請求,若是請求中須要加入 Headers 等信息,咱們就能夠利用更強大的Request對象來擴展功能,Request對象以下所示。

 

class urllib.request.Request(url, data=None, headers={},
  origin_req_host=None,
  unverifiable=False, method=None)

 urlopen() 方法能夠實現最基本請求的發起,但這幾個簡單的參數並不足以構建一個完整的請求,若是請求中須要加入 Headers 等信息,咱們就能夠利用更強大的 Request 類來構建一個請求。

構造Request對象必須傳入url參數,data數據和headers都是可選的。

最後,Request方法可使用method參數來自由選擇請求的方法,如PUT,DELETE等等,默認爲GET。

添加Headers

經過urllib發起的請求會有默認的一個Headers:"User-Agent":"Python-urllib/3.6",指明請求是由urllib發送的。

因此遇到一些驗證User-Agent的網站時,咱們須要自定義Headers,而這須要藉助於urllib.request中的Request對象。

from urllib import request

url = 'http://httpbin.org/get'
headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}

# 須要使用url和headers生成一個Request對象,而後將其傳入urlopen方法中
req = request.Request(url, headers=headers)
resp = request.urlopen(req)
print(resp.read().decode())

 

添加Cookie

爲了在請求時能帶上Cookie信息,咱們須要從新構造一個opener。

使用request.build_opener方法來進行構造opener,將咱們想要傳遞的cookie配置到opener中,而後使用這個opener的open方法來發起請求。

from http import cookiejar
from urllib import request

url = 'http://httpbin.org/cookies'
# 建立一個cookiejar對象
cookie = cookiejar.CookieJar()
# 使用HTTPCookieProcessor建立cookie處理器
cookies = request.HTTPCookieProcessor(cookie)
# 並以它爲參數建立Opener對象
opener = request.build_opener(cookies)
# 使用這個opener來發起請求
resp = opener.open(url)
print(resp.read().decode())

或者也能夠把這個生成的opener使用install_opener方法來設置爲全局的。

則以後使用urlopen方法發起請求時,都會帶上這個cookie。

# 將這個opener設置爲全局的opener
request.install_opener(opener)
resp = request.urlopen(url)

設置Proxy代理

使用爬蟲來爬取數據的時候,經常須要使用代理來隱藏咱們的真實IP。

from urllib import request

url = 'http://httpbin.org/ip'
proxy = {'http':'50.233.137.33:80','https':'50.233.137.33:80'}
# 建立代理處理器
proxies = request.ProxyHandler(proxy)
# 建立opener對象
opener = request.build_opener(proxies)

resp = opener.open(url)
print(resp.read().decode())

下載數據到本地

在咱們進行網絡請求時經常須要保存圖片或音頻等數據到本地,一種方法是使用python的文件操做,將read()獲取的數據保存到文件中。

urllib提供了一個urlretrieve()方法,能夠簡單的直接將請求獲取的數據保存成文件。

from urllib import request

url = 'http://python.org/'
request.urlretrieve(url, 'python.html')

urlretrieve()方法傳入的第二個參數爲文件保存的位置,以及文件名。

注:urlretrieve()方法是python2直接移植過來的方法,之後有可能在某個版本中棄用。

 

urllib.response

在使用urlopen()方法或者opener的open()方法發起請求後,得到的結果是一個response對象。

這個對象有一些方法和屬性,可讓咱們對請求返回的結果進行一些處理。

  • read()

    獲取響應返回的數據,只能使用一次。

  • getcode()

    獲取服務器返回的狀態碼。

  • getheaders()

    獲取返回響應的響應報頭。

  • geturl()

    獲取訪問的url。

 

urllib.parse

urllib.parse是urllib中用來解析各類數據格式的模塊。

urllib.parse.quote

在url中,是隻能使用ASCII中包含的字符的,也就是說,ASCII不包含的特殊字符,以及中文等字符都是不能夠在url中使用的。而咱們有時候又有將中文字符加入到url中的需求,例如百度的搜索地址:

https://www.baidu.com/s?wd=南北

?以後的wd參數,則是咱們搜索的關鍵詞。那麼咱們實現的方法就是將特殊字符進行url編碼,轉換成能夠url能夠傳輸的格式,urllib中可使用quote()方法來實現這個功能。

>>> from urllib import parse
>>> keyword = '南北'
>>> parse.quote(keyword)
'%E5%8D%97%E5%8C%97'

若是須要將編碼後的數據轉換回來,可使用unquote()方法。

>>> parse.unquote('%E5%8D%97%E5%8C%97')
'南北'

urllib.parse.urlencode

在訪問url時,咱們經常須要傳遞不少的url參數,而若是用字符串的方法去拼接url的話,會比較麻煩,因此urllib中提供了urlencode這個方法來拼接url參數。

>>> from urllib import parse
>>> params = {'wd': '南北', 'code': '1', 'height': '188'}
>>> parse.urlencode(params)
'wd=%E5%8D%97%E5%8C%97&code=1&height=188'

 

urllib.error

urllib中主要設置了兩個異常,一個是URLError,一個是HTTPErrorHTTPErrorURLError的子類。

HTTPError還包含了三個屬性:

  • code:請求的狀態碼

  • reason:錯誤的緣由

  • headers:響應的報頭

例子:

In [1]: from urllib.error import HTTPError

In [2]: try:
   ...:     request.urlopen('https://www.jianshu.com')
   ...: except HTTPError as e:
   ...:     print(e.code)
    
403

 

urllib3

Urllib3是一個功能強大,條理清晰,用於HTTP客戶端的Python庫。許多Python的原生系統已經開始使用urllib3。Urllib3提供了不少python標準庫urllib裏所沒有的重要特性:

  1. 線程安全

  2. 鏈接池

  3. 客戶端SSL/TLS驗證

  4. 文件分部編碼上傳

  5. 協助處理重複請求和HTTP重定位

  6. 支持壓縮編碼

  7. 支持HTTP和SOCKS代理

 

安裝

urllib3是一個第三方庫,安裝很是簡單,pip安裝便可:

pip install urllib3

 

使用

urllib3主要使用鏈接池進行網絡請求的訪問,因此訪問以前咱們須要建立一個鏈接池對象,以下所示:

>>> import urllib3
>>> http = urllib3.PoolManager()
>>> r = http.request('GET', 'http://httpbin.org/robots.txt')
>>> r.status
200
>>> r.data
'User-agent: *\nDisallow: /deny\n'

設置headers

headers={'X-Something': 'value'}
resp = http.request('GET', 'http://httpbin.org/headers', headers=headers)

設置url參數

對於GET等沒有請求正文的請求方法,能夠簡單的經過設置fields參數來設置url參數。

fields = {'arg': 'value'}
resp = http.request('GET', 'http://httpbin.org/get', fields=fields)

若是使用的是POST等方法,則會將fields做爲請求的請求正文發送。

因此,若是你的POST請求是須要url參數的話,那麼須要本身對url進行拼接。

fields = {'arg': 'value'}
resp = http.request('POST', 'http://httpbin.org/get', fields=fields)

設置代理

>>> import urllib3
>>> proxy = urllib3.ProxyManager('http://50.233.137.33:80', headers={'connection': 'keep-alive'})
>>> resp = proxy.request('get', 'http://httpbin.org/ip')
>>> resp.status
200
>>> resp.data
b'{"origin":"50.233.136.254"}\n'

 

注:urllib3中沒有直接設置cookies的方法和參數,只能將cookies設置到headers中

相關文章
相關標籤/搜索