爬蟲基礎筆記—urllib3庫的使用

urllib3庫

簡介

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

1.構造請求(request)

導入urllib3庫

import urllib3

然後需要實例化一個PoolManager對象構造請求,這個對象處理了連接池和線程池的所有細節,所以我們不用自行處理。

http = urllib3.PoolManager()

用request()方法發送一個請求

r = http.request('GET', 'http://httpbin.org/robots.txt')
b'Uesr-agent:*\nDisallow: /deny\n' 

可以用request()方法發送任意http請求,我們發一個post請求

r = http.request(
    'POST',
    'http://httpbin.org/post',
    fields=('hello':'world')
)

2.Response content

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

http = urllib3.PoolManager()
r = http.request('GET', 'http://httpbin.org/ip')
print(r.status)
print(r.data)
print(r.headers)

'''
運行結果
200
b'{\n  "origin": "221.178.125.122"\n}\n'
HTTPHeaderDict({'Date': 'Tue, 25 Feb 2020 12:00:23 GMT', 'Content-Type': 'application/json', 'Content-Length': '34', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'})
'''

3.JSON content

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

import urllib3
import json

http = urllib3.PoolManager()
r = http.request('GET', 'http://httpbin.org/ip')
print(json.loads(r.data.decode('utf-8')))

'''
運行結果
{'origin': '221.178.125.122'}
'''

4.Binary content

響應返回的數據都是字節類型,對於大量的數據我們通過

stream來處理好:
http = urllib3.PoolManager()
r = http.request('GET', 'http://httpbin.org/bytes/1024',preload_content=False)

 for chunk in r.stream(32):
     print(chunk) 

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

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

 for line in r:
     print(line) 

5.proxies

可以利用ProxyManager進行http代理操作

proxy = urllib3.ProxyManager('http://180.76.111.69:3128')
res = proxy.request('get', 'http://httpbin.org/ip')
print(res.data)

6.Request data

a.Headers

request方法中添加字典格式的headers參數去指定請求頭

http = urllib3.PoolManager()
r = http.request('GET', 'http;//httpbin.org/headers', headers={'key': 'value'})

print(json.loads(r,data,decode('utf-8')))
b.Query parameters

get,head,delete請求,可以通過提供字典類型的參數fields來添加查詢參數。

http = urllib3.PoolManager()
r = http.request(
    'GET',
    'http://httpbin.org/get',
    fields={'arg': 'value'}
)
print(json.loads(r.data.decode(utf-8))['args'])

對於post和put請求, 如果需要查詢參數,需要通過url編碼將參數編碼正確個格式然後拼接到url中

import urllib3
import json
from urllib.parse import urlencode
http = urllib3.PoolManager()
encoded_args = urlencode({'args': 'value'})
url = 'http://httpbin.org/post?' + encode_args
r = http.request('POST', url)
print(json.loads(r.data.decode('utf-8'))['args'])
c.Form data

對於put和post請求,需要提供字典類型的參數field來傳遞form表單數據。

r = http.request('POST', 'http://httpbin/post',fields={'field: 'value'})
print(json.loads(r.data.decode('utf-8'))['form']) 
d.JSON

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

http = urllib3.PoolManager()
data = {'attribute': 'value'}
encode_data = json.dumps(data).encode('utf-8')
r = http.request(
    'post'
    'http://httpbin.org/post',
    body=encoded_data,
    headers={'Content-Type': 'application/json'}
)
print(json.load(r.data.decode('utf-8'))['json']) 
e.Files&binary data

對於文件上傳,我們可以模仿瀏覽器表單的方式

with open('example.text') as f:
    file_data = f.read()
r = http.request(
    'POST',
    'http://httpbin.org/post',
    fields={
        'filefied':('example.txt', file_data),
})    
print(json.loads(r.data.decode('utf-8'))['files'])

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

http = urllib3.PoolManger()
with open('example.jpg','rb') as f:
    binary_data = f.read()
r = http.request(
    'post',
    'http://httpbin.org/post',
    body=binary_data,
    headers={'Content-Type':'image/jpeg'}
)
print(json.loads(r.data.decode('utf-8')))

7.爬蟲一般開發流程

	a.找到目標數據
	b.分析請求流程
	c.構造http請求
	d.提取清洗數據
	e.數據持久化
案例:1.利用urllib3 下載 百度圖片首頁所有圖片,保存到當前文件夾下的imgs文件夾
import urllib3
import re
'''
下載百度首頁所有圖片
'''
# 1.尋找目標數據
page_url = 'https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%CD%BC%C6%AC&fr=ala&ala=1&alatpl=adress&pos=0&hs=2&xthttps=111111'
# 2.分析請求流程
# 圖片是瀏覽器下載下來的
# 圖片的url,會比圖片更早的下載回來
# 下載html
http = urllib3.PoolManager()
res = http.request('GET', page_url)
html = res.data.decode('utf-8')     # 網頁源碼搜索charset,查看編碼類型
# 提取url
img_urls = re.findall(r'"thumbURL":"(.*?)"', html)
# 加上headers僞裝
header = {
    "Referer": "https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%CD%BC%C6%AC&fr=ala&ala=1&alatpl=adress&pos=0&hs=2&xthttps=111111"

}
# 遍歷 下載
for index, img_url in enumerate(img_urls):
    img_res = http.request('GET', img_url, headers=header)
    # print(img_res.data)
    # 動態拼接文件名
    img_name = '%s.%s' % (index, img_url.split('.')[-1])
    with open('img_name', 'wb') as f:
        f.write(img_res.data)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章