urllib和urllib3


  • urllib庫

urllib 是一個用來處理網絡請求的python標准庫,它包含4個模塊。

urllib.request---請求模塊,用於發起網絡請求

urllib.parse---解析模塊,用於解析URL

urllib.error---異常處理模塊,用於處理request引起的異常

urllib.robotparser robots.tx---用於解析robots.txt文件

 

urllib.request模塊

 

request模塊主要負責構造和發起網絡請求,並在其中添加Headers,Proxy等。 利用它可以模擬瀏覽器的請求發起過程。

  1. 發起網絡請求
  2. 操作cookie
  3. 添加Headers
  4. 使用代理

關於urllib.request.urlopen參數的介紹

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

urlopen是一個簡單發送網絡請求的方法。它接收一個字符串格式的url,它會向傳入的url發送網絡請求,然后返回結果。

 

先寫一個簡單的例子:

from urllib import request
response = request.urlopen(url='http://www.httpbin.org/get') print(response.read().decode())

 

urlopen默認會發送get請求,當傳入data參數時,則會發起POST請求。data參數是字節類型、者類文件對象或可迭代對象。

from urllib import request
response = request.urlopen(url='http://www.httpbin.org/post', data=b'username=q123&password=123') print(response.read().decode())

 

還才可以設置超時,如果請求超過設置時間,則拋出異常。timeout沒有指定則用系統默認設置,timeout只對,http,https以及ftp連接起作用。它以秒為單位,比如可以設置timeout=0.1 超時時間為0.1秒。

from urllib import request
response = request.urlopen(url='https://www.baidu.com/',timeout=0.1)

Request對象

 

利用openurl可以發起最基本的請求,但這幾個簡單的參數不足以構建一個完整的請求,可以利用更強大的Request對象來構建更加完整的請求。

 

1 . 請求頭添加

通過urllib發送的請求會有一個默認的Headers: “User-Agent”:“Python-urllib/3.6”,指明請求是由urllib發送的。所以遇到一些驗證User-Agent的網站時,需要我們自定義Headers把自己偽裝起來。

from urllib import request
headers ={
    'Referer': 'https://www.baidu.com/s?ie=utf-8&f=3&rsv_bp=1&tn=baidu&wd=python%20urllib%E5%BA%93&oq=python%2520urllib%25E5%25BA%2593&rsv_pq=947af0af001c94d0&rsv_t=66135egC273yN5Uj589q%2FvA844PvH9087sbPe9ZJsjA8JA10Z2b3%2BtWMpwo&rqlang=cn&rsv_enter=0&prefixsug=python%2520urllib%25E5%25BA%2593&rsp=0',
     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
}
response = request.Request(url='https://www.baidu.com/',headers=headers)
response = request.urlopen(response)
print(response.read().decode())

2. 操作cookie

在開發爬蟲過程中,對cookie的處理非常重要,urllib的cookie的處理如下案例

from urllib import request
from http import cookiejar
# 創建一個cookie對象
cookie = cookiejar.CookieJar()

# 創一個cookie處理器
cookies = request.HTTPCookieProcessor(cookie)

# 以它為參數,創建opener對象
opener = request.build_opener(cookies)
# 使用這個opener 來發請求
res =opener.open('https://www.baidu.com/')

print(cookies.cookiejar)

3. 設置代理

運行爬蟲的時候,經常會出現被封IP的情況,這時我們就需要使用ip代理來處理,urllib的IP代理的設置如下:

from urllib import request
url ='http://httpbin.org/ip'

#代理地址
proxy ={'http':'172.0.0.1:3128'}

# 代理處理器
proxies =request.ProxyBasicAuthHandler(proxy)

# 創建opener對象
opener = request.build_opener(proxies)

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

 

 urlib庫中的類或或者方法,在發送網絡請求后,都會返回一個urllib.response的對象。它包含了請求回來的數據結果。它包含了一些屬性和方法,供我們處理返回的結果

read() 獲取響應返回的數據,只能用一次 

readline() 讀取一行 

info() 獲取響應頭信息 

geturl() 獲取訪問的url

getcode() 返回狀態碼 

 

urllib.parse模塊

 

parse.urlencode() 在發送請求的時候,往往會需要傳遞很多的參數,如果用字符串方法去拼接會比較麻煩,parse.urlencode()方法就是用來拼接url參數的。

from urllib import parse
params = {'wd':'測試', 'code':1, 'height':188}
res = parse.urlencode(params)
print(res)

打印結果為wd=%E6%B5%8B%E8%AF%95&code=1&height=188

 

也可以通過parse.parse_qs()方法將它轉回字典

print(parse.parse_qs('wd=%E6%B5%8B%E8%AF%95&code=1&height=188'))

 

urllib.error模塊

error模塊主要負責處理異常,如果請求出現錯誤,我們可以用error模塊進行處理 主要包含URLError和HTTPError

URLError:是error異常模塊的基類,由request模塊產生的異常都可以用這個類來處理

HTTPError:是URLError的子類,主要包含三個屬性

  1. Code:請求的狀態碼
  2. reason:錯誤的原因
  3. headers:響應的報頭
from urllib import request,error
try:
    response = request.urlopen("http://pythonsite.com/1111.html")
except error.HTTPError as e:
    print(e.reason)
    print(e.code)
    print(e.headers)
except error.URLError as e:
    print(e.reason)

else:
    print("reqeust successfully")

urllib.robotparse模塊

 

robotparse模塊主要負責處理爬蟲協議文件,robots.txt.的解析。 https://www.taobao.com/robots.txt

Robots協議(也稱為爬蟲協議、機器人協議等)的全稱是“網絡爬蟲排除標准”(Robots Exclusion Protocol),網站通過Robots協議告訴搜索引擎哪些頁面可以抓取,哪些頁面不能抓取

 

  • urllib庫
  • urllib3 是一個基於python3的功能強大,友好的http客戶端。越來越多的python應用開始采用urllib3.它提供了很多python標准庫里沒有的重要功能

安裝:

pip install urllib3

構造請求(request)

import urllib3
# 創建連接
http = urllib3.PoolManager()
# 發送請求
res = http.request('GET','https://www.baidu.com/')
# 狀態碼
print(res.status)
# 返回的數據
print(res.data.decode())

發送post請求

import urllib3
# 創建連接
http = urllib3.PoolManager()
# 發送請求
res = http.request('POST','https://www.baidu.com/',fields={'hello':'word'})
# 狀態碼
print(res.status)
# 返回的數據
print(res.data.decode())

http響應對象提供status, data,和header等屬性

status--狀態碼

data--讀取返回的數據

header--請求頭

 

 

返回的json格式數據可以通過json模塊,load為字典數據類型。

 

import json
data={'attribute':'value'}
encode_data= json.dumps(data).encode()

r = http.request('POST',
                     'http://httpbin.org/post',
                     body=encode_data,
                     headers={'Content-Type':'application/json'}
                 )
print(r.data.decode('unicode_escape'))

 

響應返回的數據都是字節類型,對於大量的數據我們通過stream來處理更好

import urllib3
http = urllib3.PoolManager()
r =http.request('GET','http://httpbin.org/bytes/1024',preload_content=False)
for chunk in r.stream(32):
    print(chunk)

也可以當做一個文件對象來處理

import urllib3
http = urllib3.PoolManager()
r =http.request('GET','http://httpbin.org/bytes/1024',preload_content=False)
for chunk in r:
    print(chunk)

urllib3庫Proxies(代理IP)

import urllib3
proxy = urllib3.ProxyManager('http://172.0.0.1:3128')
res =proxy.request('GET','https://www.baidu.com/')
print(res.data)

 urllib3庫headers(添加請求頭)

 

import urllib3
http = urllib3.PoolManager()
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'
}
res = http.request('GET','https://www.baidu.com/',headers=headers)
print(res.data)

 

 

JSON 當我們需要發送json數據時,我們需要在request中傳入編碼后的二進制數據類型的body參數,並制定Content-Type的請求頭

JSON:在發起請求時,可以通過定義body 參數並定義headers的Content-Type參數來發送一個已經過編譯的JSON數據:
import json
data={'attribute':'value'}
encode_data= json.dumps(data).encode()

r = http.request('POST',
                     'http://httpbin.org/post',
                     body=encode_data,
                     headers={'Content-Type':'application/json'}
                 )
print(r.data.decode('unicode_escape'))

 

對於二進制的數據上傳,我們用指定body的方式,並設置Content-Type的請求頭

#使用multipart/form-data編碼方式上傳文件,可以使用和傳入Form data數據一樣的方法進行,並將文件定義為一個元組的形式     (file_name,file_data):
with open('1.txt','r+',encoding='UTF-8') as f:
    file_read = f.read()

r = http.request('POST',
                 'http://httpbin.org/post',
                 fields={'filefield':('1.txt', file_read, 'text/plain')
                         })
print(r.data.decode('unicode_escape'))

#二進制文件
with open('websocket.jpg','rb') as f2:
    binary_read = f2.read()

r = http.request('POST',
                 'http://httpbin.org/post',
                 body=binary_read,
                 headers={'Content-Type': 'image/jpeg'})
#
# print(json.loads(r.data.decode('utf-8'))['data'] )
print(r.data.decode('utf-8'))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM