【python&爬蟲】快速入門urllib庫和requests庫

一.urllib庫基本介紹

urllib庫是python內置的HTTP請求庫,它可以看作處理URL的組件集合。urllib庫包含三大組件:   
	1.urllib.request 請求模塊
    2.urllib.error 異常處理模塊
    3.urllib.parse URL解析模塊
    4.urllib.robotparser robots.txt解析模塊

注意:python2使用的是urllib2模塊,python3出現後,之前的python2中的urllib2模塊被
移植到了urllib.request模塊中了,之前的urllib中的函數的路徑也發生了改變

二.urllib.request 請求模塊

1.urlopen方法參數解析

urlopen方法用於向指定URL發送get請求或者post請求

           def urlopen(
           url,     	   #url參數,標識目標網站中的位置,表示url地址
           data=None,      #1.用來指明向服務器發送請求的額外信息 http協議是唯一支持data參數的協議
                            data默認是None,此時發送的時get請求;當設置參數時,需要使用post請求
                            2.使用urllib.parse.urlencode()方法將data轉換爲標準格式,而這個參數接收
                            的類型是鍵值對類型
                            3.data必須是一個bytes對象

           timeout=socket._GLOBAL_DEFAULT_TIMEOUT,*,      #可選參數,用於設置超時時間,單位秒

           cafile=None,capath=None,cadefault=False, #這三個參數用於實現CA證書的HTTPS請求,很少使用
           context=None #實現ssl加密傳輸,很少使用
           )

1.1.發送get請求

from urllib import request,parse
# 使用urlopen方法向url方式請求
response = request.urlopen("https://www.baidu.com/")
# 使用read() 方法讀取到頁面內容,使用decode()方法解碼 utf-8
html = response.read().decode('utf-8')
# 打印結果
print(html)

1.2.發送post請求(設置data參數)

如果設置data參數那麼請求方式會改爲post,默認是get請求。這兩種請求方式最大的區別在於:get方式直接使用URL訪問,在URL中包含了所有的參數;post方式則不會在URL中顯示所有的參數,參數包含在請求體中,會更加安全。

注意:1.需要使用urllib.parse.urlencode(data)將data轉換爲標準格式
2.data必須是一個bytes對象

from urllib import request,parse
# data參數使用,使用data參數,那麼就是post請求 encode('utf-8'))使用utf-8編碼方式
data = bytes(parse.urlencode({'world':'hello'}).encode('utf-8'))
#http://httpbin.org/ 是一個簡單的HTTP請求和響應服務。
#這裏發送的就是post請求
response2 = request.urlopen("http://httpbin.org/post",data=data)
# 這裏需要用utf-8編碼解碼
html2 = response2.read().decode('utf-8')
print(html)

1.3.設置timeout參數

該參數用於設置超時時間,單位是秒

from urllib import request,parse
# timeout參數使用,超時時間設置成一秒
response3 = request.urlopen("https://www.baidu.com/",timeout=1)
html3 = response3.read()

1.4.HTTPResponse對象

使用上述urlopen方法發送http請求後,服務器返回的響應內容會封裝在一個HTTPResponse對象中,如下代碼演示:

from urllib import request
# 傳入URL構造出Request對象
url = request.Request("https://www.baidu.com/")
response = request.urlopen(url)
print(type(response)) 
#輸出結果:<class 'http.client.HTTPResponse'>

HTTPResponse類提供了URL,狀態碼,響應內容等方法,常見方法如下:

方法名 解釋
geturl() 獲取當前請求的URL
info() 返回頁面元信息
getcode() 返回響應碼

代碼演示

from urllib import request
# 傳入URL構造出Request對象
url = request.Request("https://www.baidu.com/")
response = request.urlopen(url)
# print(type(response)) #<class 'http.client.HTTPResponse'>
# 獲取當前請求的URL
print(response.geturl())
#返回頁面元信息
print(response.info())
# 返回狀態碼
print(response.getcode())

輸出結果
在這裏插入圖片描述

2.構造Request對象

細心的朋友已經發現,urlopen()方法沒有接收header的參數,如果需要添加HTTP報頭,這時就需要用到Request對象
下面是Request的構造方法

class Request:
    def __init__(self, url, data=None, headers={},
                 origin_req_host=None, unverifiable=False,
                 method=None):

我們可以將url,data,headers等參數傳入構造方法,構建一個Request對象
下面是爬蟲百度翻譯的案例

from urllib import request, parse

url = "https://fanyi.baidu.com/sug"
header = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
}
fromdata = {
	# 待翻譯的英語單詞
    "kw": "China"
}
# 構建data對象
data = bytes(parse.urlencode(fromdata).encode("utf-8"))
# # 構建Request對象
request1 = request.Request(url=url, headers=header, data=data)
responce = request.urlopen(request1)
# 將Unicode編碼轉換成中文
html = responce.read().decode("unicode-escape")
print(html)

輸出結果
在這裏插入圖片描述
*

三.urllib.parse URL解析模塊

URL編碼轉換,就是將中文或者其他特殊符號轉換成URL編碼(URL encoding),這個編碼也稱作百分號編碼(Percent-encoding), 是特定上下文的統一資源定位符 (URL)的編碼機制
URL編碼和解碼實例代碼

from urllib import parse
data = {
    "a": "爬蟲",
}
# 按照UrlEncode對data進行編碼
result = parse.urlencode(data) #a=%E7%88%AC%E8%99%AB
print(result)
# 對該編碼進行解碼
result2 = parse.unquote(result)
print(result2)

輸出結果
在這裏插入圖片描述

四.代理服務器

很多網站會檢測某一段時間某個IP的訪問次數,如果同一IP訪問過於頻繁,那麼該網站會禁止該IP的訪問。針對這種情況,可以使用代理服務器,每隔一段時間換一個代理。如果某個IP被禁,可以換成其他IP繼續爬取從而有效解決網站禁止訪問的情況;代理多用於防止“反爬蟲”機制。

1.使用自定義opener對象發送請求

前面我們一直使用的是urlopen方法發送請求,其實這也是一個opener。但是urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高級功能,如果需要用到這些高級功能,這時就需要自定義opener了。
構建opener對象實例代碼

from urllib import request
# 構建一個HTTPHandler處理器對象,支持處理HTTP請求
http_handler = request.HTTPHandler()
# 創建支持處理HTTP請求的opener對象
'''
從處理程序列表創建opener對象。
opener將使用幾個默認處理程序,包括支持
適用於HTTP、FTP和HTTPS。
如果作爲參數傳遞的任何處理程序是
默認處理程序,將不使用默認處理程序。
'''
opener = request.build_opener(http_handler)
# 構建Request請求
res = request.Request("https://www.baidu.com/")
# 使用指定要的opener對象的open方法,發送request請求
response = opener.open(res)
print(response.read().decode("utf-8"))

2.設置代理服務器

我們可以使用urllib.request中的ProxyHandler()方法來設置代理服務器

from urllib import request
#構建兩個代理Handler,一個有代理IP,一個沒有代理IP
httpProxy_handler = request.ProxyHandler({"http":"192.168.220.13:80"})
nullProxt_handler = request.ProxyHandler()
#設置一個代理開關
proxy_loop = True
# 根據代理開關是否打開,使用不同的代理
if proxy_loop:
    opener = request.build_opener(httpProxy_handler)
else:
    opener = request.build_opener(nullProxt_handler)
response = opener.open("https://www.baidu.com/")
print(response.read().decode("utf-8"))

五.requests庫

requests庫是基於python開發的HTTP庫,與urllib標準庫相比,代碼要簡潔。實際上,requests庫是在urllib的基礎上進行了高度封裝,它不僅繼承了urllib庫的所有特性,而且還支持Cookie保存會話,自動確定響應內容的編碼等。

1.requests庫常用類:

解釋
requests.Request 表示請求對象,用於將一個請求發送到服務器
requests.Response 表示響應對象,其中包含服務器對HTTP請求的響應
requests.Session 表示請求會話,提供Cookie持久性,連接池和配置

2.requests庫的請求函數

函數 功能說明
requests.request() 構造一個請求,支持以下各方法的基礎方法
requests.get() 請求指定頁面信息,並返回實體主體
requests.post() 向指定資源提交數據進行處理請求(如提交表單或者上傳文件),數據包含在請求體中。post請求可能會導致新的資源的建立和已有資源的修改
requests.head() 類似於get請求,只不過返回的響應中沒有具體內容,用於獲取報頭
requests.put() 這種請求方式下,從客戶端向服務器傳送的數據取代指定的文檔內容
requests.delete() 請求指定服務器刪除指定頁面
requests.patch() 向HTML網頁提交局部修改請求

3.返回響應

Response類用於動態的響應客戶端的請求,控制發送給用戶的信息,並且將動態地生成響應,包括狀態碼,網頁的內容等

Response的常用屬性

屬性 說明
status_code HTTP請求的返回狀態,200代表連接成功,404表示失敗
text HTTP響應內容的字符串形式,即URL對應的頁面內容
encoding 從HTTP請求頭中猜測的響應內容編碼方式
apparent_encoding 從內容中分析出響應編碼方式(備選編碼方式)
content HTTP響應的二進制形式

Response類會自動解碼來自服務器的內容,並且大多數的Unicode字符集都可以被無縫地解碼。
代碼示例,你會發現requests庫比urllib庫簡單好多

import requests

url = "https://www.baidu.com/"
response = requests.get(url)
#以字符串的形式返回
print(response.text)
# 查看文本編碼
print(response.encoding)
# 查看響應碼
print(response.status_code)

輸出結果
在這裏插入圖片描述

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