HTTP庫之urllib庫

本文涉及的主要內容爲urllib類庫下的request、error、parse模塊

一、介紹

  python2中分urllib、urllib2,python3中爲urllib。
  Python內置的HTTP請求庫(默認安裝)。

二、四大模塊

  • request:打開URL(模擬發送請求,可理解爲輸入瀏覽器輸入網址回車一樣)
  • error:異常處理,保證程序不會異常中止
  • parse:解析URL(拆分、解析、合併等)
  • robotparser:識別網站robots.txt文件

三、實例

3.1 urlopen() 基本請求

3.1.1 抓取網頁源碼【例】

(抓取csdn站點源代碼)

import urllib.request

response = urllib.request.urlopen("https://csdn.net")
print(response.read().decode('utf-8'))

在這裏插入圖片描述

3.1.2 查看返回類型【例】

import urllib.request

response = urllib.request.urlopen("https://csdn.net")
print(type(response))

在這裏插入圖片描述

3.1.3 讀取返回狀態碼【例】

import urllib.request

response = urllib.request.urlopen("https://csdn.net")
print(response.status)

在這裏插入圖片描述

3.1.4 獲取請求頭信息【例】

import urllib.request

response = urllib.request.urlopen("https://csdn.net")
print(response.getheaders())

在這裏插入圖片描述

A data數值傳遞【例】

import urllib.request
import urllib.parse

# 使用data需將bytes()方法將參數轉化成字節流編碼格式內容,第一個參數需要urllib.parse模塊中的urlencode()方法將參數字典轉化成字符串,第二個指定編碼格式
data = bytes(urllib.parse.urlencode({'word':'hello'}),encoding='utf-8')
response = urllib.request.urlopen('http://httpbin.org/post',data=data)
print(response.read())

在這裏插入圖片描述

B timeout超時【例】

(設置超時1s後服務器沒響應拋出異常,該異常屬於urllib.error)

import urllib.request

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

在這裏插入圖片描述

a. 超時處理【例】

可以通過超時時間控制網頁長時間未響應時跳出異常,響應超時跳過抓取。(超時處理)

import socket
import urllib.request
import urllib.error
try:
	response = urllib.request.urlopen('http://httpbin.org/get',timeout=0.1)
# 捕獲URLError異常
except urllib.error.URLError as e:
	# 判斷異常時socket.timeout類型(超時異常)
	if isinstance(e.reason,socket.timeout):
		print('Time Out')

3.2 request請求

3.2.1 抓取網頁源碼【例】

import urllib.request

# 構造數據結構,調用Request類將請求獨立成對象request
request = urllib.request.Request('https://csdn.net')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

在這裏插入圖片描述

自定義請求頭(request多參數傳遞)【例】

from urllib import request,parse

url = 'http://httpbin.org/post'
headers = {
	# 僞裝瀏覽器
	'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0',
	'Host':'httpbin.org'
}
# 定義data數據對象
dict = {
	'name':'Germey'
}
# 將data數據轉字節流(bytes()方法和urlencode()方法)
data = bytes(parse.urlencode(dict),encoding='utf-8')
# request多參數構造
req = request.Request(url=url, data=data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

在這裏插入圖片描述

3.3 request請求高級用法

3.3.0 Handler介紹

  包含各種處理器,專門處理登錄驗證、cookies、代理設置

  • urllib.request模塊中的BaseHandler類是其它Handler的父類

(其它各種Handler子類繼承BaseHandler類)

  • HTTPRedirectHandler:處理重定向
  • HTTPCookieProcessor:處理Cookies
  • ProxyHandler:設置代理,默認爲空
  • HTTPPasswordMgr:管理密碼,維護用戶名和密碼錶
  • HTTPBasicAuthHandler:管理認證(Basic Auth認證問題)

3.3.1 Basic Auth認證頁爬取【例】

(如爬取如下Basic認證頁面,需要輸入用戶名和密碼才能訪問具體網頁)
在這裏插入圖片描述
》》如果正常的爬取該頁面時會報如下錯誤(HTTP狀態碼401,需要授權登錄)
在這裏插入圖片描述

from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError

# 定義目標對象信息
username = 'Kevin'
password = '123456'
url = 'http://192.168.226.129/'

# 處理登錄登錄驗證
# 創建密碼管理對象,保存需要處理的用戶名和密碼
p = HTTPPasswordMgrWithDefaultRealm()
# 利用add_password類添加賬戶信息,第一個參數realm是與遠程服務器相關域信息一般都是None(建立處理驗證的Handler)
p.add_password(None, url, username, password)
# 解決認證問題(構建一個HTTP用戶名/密碼驗證的HTTPBasicAuthHandler處理器對象,參數是創建的密碼管理對象)
auth_handler = HTTPBasicAuthHandler(p)
# 利用build_opener()方法構建opener,發送請求時相當於驗證成功
opener = build_opener(auth_handler)

# 處理異常
try:
	result = opener.open(url)
	html = result.read().decode('utf-8')
	# 獲取到的結果就是驗證後的源碼信息
	print(html)
# 捕捉錯誤對象
except URLError as e:
	# 打印錯誤代碼
	print(e.code)
	# 打印錯誤原因
	print(e.reason) 

(認證正確返回認證後的源碼:)
在這裏插入圖片描述
(認證錯誤返回錯誤代碼和原因:)401,需要用戶授權驗證,這裏是用戶名密碼錯誤
在這裏插入圖片描述

Tips:這裏的站點是爲了方便測試自己搭建的,先搭建一個Apache,然後設置訪問認證即可,詳情可參考:LAMP環境搭建、Apache訪問認證

3.3.2 添加使用代理【例】

(本地添加一個代理,運行在9743端口之上)

from urllib.request import ProxyHandler,build_opener
from urllib.error import URLError

# 使用ProxyHandler設置添加代理
proxy_handler = ProxyHandler({
	'http':'http://127.0.0.1:9743',
	'https':'https://127.0.0.1:9743'
})
# 利用build_opener()方法和Handler構造opener
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)

在這裏插入圖片描述

勾選了自動檢測設置依舊報錯
在這裏插入圖片描述

A CookieJar基礎介紹

使用爬蟲時,會用到Cookie進行模擬登錄訪問,會使用到http.cookiejar庫中的CookieJar來實現,CookieJar有一些子類分別是FileCookieJar,MozillaCookieJar,LWPCookieJar
(一般使用CookieJar(),如果和本地交互使用MozillaCookieJar()或LWPCookieJar() )

  • CookieJar:管理HTTP cookie值、存儲HTTP請求生成的Cookie,向傳出的HTTP請求添加cookie對象。整個cookie存儲在內存中,對cookie進行實例垃圾回收後cookie也將丟失
  • FileCookieJar(filename, delayload=None, policy=None):CookieJar派生而來,用來創建FileCookieJar實例,檢索Cookie信息並存儲到文件中。(fielname:存儲cookie的文件名;delayload:爲True時支持延時訪問文件,即只有需要時纔讀取文件或在文件中存儲數據)
  • MozillaCookieJar(filename, delayload=None, policy=None):FileCookieJar派生而來,創建與Mozilla瀏覽器cookies.txt兼容的FileCookieJar實例。
  • LWPCookieJar(filename, delayload=None, policy=None):從FileCookieJar派生來,創建與libwww-perl標準的Set-Cookie3文件格式兼容的FileCookieJar實例

3.3.3 獲取網站cookie【例】

(使用Handler將網站自定義的cookie獲取下來)

import http.cookiejar,urllib.request
from urllib.request import build_opener

# 聲明CookieJar對象,管理存儲HTTP cookie值
cookie = http.cookiejar.CookieJar()
# 處理Cookie
c_handler = urllib.request.HTTPCookieProcessor(cookie)
# 使用build_opener()方法構建opener
opener = build_opener(c_handler)
response = opener.open('https://www.baidu.com')
print(cookie)	# 演示理解用
print('\n')		# 演示理解用
for item in cookie:
	print(item.name+"="+item.value)

(爲了方便理解for循環中自定義的cookie,下面黃框內是未經過處理的Cookie)
在這裏插入圖片描述

3.3.4 生成Mozilla兼容cookie【例】

from urllib.request import HTTPCookieProcessor,build_opener
import http.cookiejar,urllib.request

# 定義保存文件
filename = 'cookies_file.txt'
# 聲明與Mozilla瀏覽器兼容的FileCookieJar實例
cookie = http.cookiejar.MozillaCookieJar(filename)
# 處理cookie
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = build_opener(handler)
response = opener.open('https://www.baidu.com')
# 保存cookie到文件(ignore_discard:即使cookie將要唄丟棄也保存; ignore_expires:即使該文件中的cookie已過期也保存)
cookie.save(ignore_discard=True, ignore_expires=True) 

(運行後本地和運行python腳本同級目錄下會生成對應的文件)
在這裏插入圖片描述

3.3.5 生成LWP格式cookie

from urllib.request import HTTPCookieProcessor,build_opener
import http.cookiejar,urllib.request

filename = 'cookies_file.txt'
cookie = http.cookiejar.LWPCookieJar(filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = build_opener(handler)
response = opener.open('http://www.baidu.com')
cookie.save(ignore_discard=True, ignore_expires=True)

在這裏插入圖片描述

3.3.6 讀取使用cookie

》》本地先生成一個LWP格式的cookie文件cookies.txt(代碼如3.6.5)
在這裏插入圖片描述
》》讀取使用本地的cookie去訪問指定站點

import http.cookiejar, urllib.request
from urllib.request import build_opener

# 指定使用讀取LWP格式的cookie文件
cookie = http.cookiejar.LWPCookieJar()
# load()方法讀取本地cookie文件
cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
# 構造處理cookie的HTPPCookieProcessor處理器對象對本地cookie進行處理
handler = urllib.request.HTTPCookieProcessor(cookie)
# 構建opener
opener = urllib.request.build_opener(handler)
response = opener.open('https://www.csdn.net')
print(response.read().decode('utf-8'))

》》成功使用本地的cookie讀取指定站點的源代碼
在這裏插入圖片描述

3.4 異常處理

爲了防止程序因報錯而異常終止,urllib的error模塊定義了由request模塊產生的異常。

3.4.1 URLError

urllib庫的error模塊,由request模塊產生的異常都可以由這個捕獲這個類來處理。

from urllib import request,error

try:
	# 打開一個不存在的頁面
	response = request.urlopen('https://csdn.net/1')
except error.URLError as e:
	print(e.reason)

在這裏插入圖片描述

3.4.2 HTTPError

URLError的子類,專門處理HTTP請求錯誤,如認證請求失敗等。

三個屬性
  • code:返回HTTP狀態碼
  • reason:同父類一樣,返回錯誤原因
  • headers:返回請求頭

(捕獲錯誤異常,輸出三個錯誤狀態碼、錯誤原因、返回頭信息)

from urllib import request,error

try:
	response = request.urlopen('https://csdn.net/1')
except error.HTTPError as e:
	print(e.reason, e.code, e.headers, sep='\n')

在這裏插入圖片描述

3.4.3 捕獲子類、父類錯誤

由於HTTPError是URLError的子類,我們可以先捕獲子類錯誤然後再捕獲父類錯誤

(如果不是HTTPError異常就是URLError異常)

from urllib import request,error

try:
	response = request.urlopen('https://csdn.net/1')
except error.HTTPError as e:
	print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
	print(e.reason)
else:
	print('Request Successfully')

在這裏插入圖片描述

3.5 解析鏈接

3.5.1 urlparse()(拆解URL)

url識別和分段

from urllib.parse import urlparse

result = urlparse('https://www.baidu.com/index.html;user?id=5#command')
print(type(result), result)

(拆分爲6部分)

  • scheme(協議)
  • netloc(域名)
  • path(訪問路徑)
  • params(參數)
  • query(查詢條件)
  • fragment(錨點)
    在這裏插入圖片描述
A URL字段獲取

(用屬性/索引獲取)
在這裏插入圖片描述

3.5.2 urlunparse() (拼接URL)

實現對URL構造,urlunparse()中接收的必須是6位的參數

from urllib.parse import urlunparse

data=['https','www.baidu.com','index.html','user','a=6','']
print(urlunparse(data))

在這裏插入圖片描述

3.5.3 urlsplit()(拆解URL)

拆解URL,返回5個結果,params合併到路徑

from urllib.parse import urlsplit

result = urlsplit('https://www.baidu.com/index.html;user?id=5#command')
print(result,'\n')
# 可以使用屬性或者索引取值
print(result.path)

在這裏插入圖片描述

3.5.4 urlunsplit()(拼接URL)

將鏈接各個部分拼接成完成鏈接

在這裏插入圖片描述

3.5.5 urlencode()(構造URL get請求)

通過字典構造get請求

在這裏插入圖片描述

3.5.6 parse_qs() (提取URL get請求參數-字典)

反序列化get請求參數,轉換爲字典

在這裏插入圖片描述

3.5.7 parse_qsl()(提取URL get請求參數-元組)

反序列化get請求參數,轉換爲字典

在這裏插入圖片描述

3.5.8 quote()(URL編碼)

將內容轉換爲URL編碼的格式

在這裏插入圖片描述

3.5.9 unquote()(URL解碼)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章