網絡請求
urlopen函數用法
urllib庫
urllib庫是python中一個最基本的網絡請求庫。可以模擬瀏覽器的行為,向指定的服務器發送一個請求,并可以保存服務器返回的數據
urlopen函數
在python3的urllib庫中,所有和網絡請求相關的方法都被集成到urllib.request模塊下面了,下面先看下urlopen函數基本使用:
from
urllib
import
request
resp
=
request
.
urlopen
(
'http://www.baidu.com'
)
print
(
resp
.
read
(
)
)
實際上,使用瀏覽器訪問百度,右鍵查看源代碼。就會發現,打印處理的內容就是和請求的內容一摸一樣的,也就是說,上面的三行代碼已經幫我們將百度首頁的內容全部爬下來了
這里對urlopen函數進行詳細講解:
- url:請求的url
- data:請求的data,如果設置了這個值,那么請求將會變成post請求
- 返回值:返回值是一個http.client.HTTPResponse對象,這個對象是一個類文件句柄對象有read(size)、readline、readlines以及getcode等方法
urlretrieve函數
這個函數可以方便的將網頁上的一個文件保存到本地。以下代碼可以非常方便的將百度的首頁下載到本地
from
urllib
import
request
request
.
urlretrieve
(
'http://www.baidu.com/'
,
'baidu.html'
)
使用這個函數,可以方便我們將圖片或者其他的內容下載到本地
urlencode函數
用瀏覽器發送請求的時候,如果url中包含了中文或者其他特殊符號,那么瀏覽器會自動給我們進行編碼,而如果使用代碼發送請求,那么就必須手動進行編碼,這時候就應該使用urlencode函數來實現,urlencode可以把字典數據轉換為URL編碼的數據,示例代碼如下:
from
urllib
import
parse
data
=
{
'name'
:
'爬蟲基礎'
,
'greet'
:
'hello world'
,
'age'
:
100
}
result
=
parse
.
urlencode
(
data
)
print
(
result
)
name
=
%
E7
%
88
%
AC
%
E8
%
99
%
AB
%
E5
%
9F
%
BA
%
E7
%
A1
%
80
&
greet
=
hello
+
world
&
age
=
100
parse_qs函數
可以將經過編碼后的url參數進行解碼(這個是配合上面urlencode函數配合使用的),示例代碼如下:
from
urllib
import
parse
params
=
{
'name'
:
'張三'
,
'age'
:
18
,
'greet'
:
'hello world'
}
qs
=
parse
.
urlencode
(
params
)
print
(
qs
)
result
=
parse
.
parse_qs
(
qs
)
print
(
result
)
name
=
%
E5
%
BC
%
A0
%
E4
%
B8
%
89
&
age
=
18
&
greet
=
hello
+
world
{
'name'
:
[
'張三'
]
,
'age'
:
[
'18'
]
,
'greet'
:
[
'hello world'
]
}
urlparse和urlsplit
有時候拿到一個url,想要對這個url中的各個組成部分進行分割,那么這時候就可以使用urlparse或者urlsplit來進行分割
首先來看下urlparse
from
urllib
import
parse
url
=
'http://www.baidu.com/s?wb=python&username=abc#1'
result
=
parse
.
urlparse
(
url
)
print
(
result
)
ParseResult
(
scheme
=
'http'
,
netloc
=
'www.baidu.com'
,
path
=
'/s'
,
params
=
''
,
query
=
'wb=python&username=abc'
,
fragment
=
'1'
)
如果僅僅只想獲取中間某一個內容,可以使用如下的方式來進行獲取
print
(
result
.
scheme
)
http
其次來看下urlsplit
url
=
'http://www.baidu.com/s?wb=python&username=abc#1'
result
=
parse
.
urlsplit
(
url
)
print
(
result
)
SplitResult
(
scheme
=
'http'
,
netloc
=
'www.baidu.com'
,
path
=
'/s'
,
query
=
'wb=python&username=abc'
,
fragment
=
'1'
)
對比可以發現,在使用urlsplit的時候,中間缺少了一個params的參數,這里的params在現在的爬蟲中間用到的比較少,這里獲取的內容就是 ;和?之間的內容,如下所示
from
urllib
import
parse
url
=
'http://www.baidu.com/s;hello?wb=python&username=abc#1'
result
=
parse
.
urlparse
(
url
)
print
(
result
)
ParseResult
(
scheme
=
'http'
,
netloc
=
'www.baidu.com'
,
path
=
'/s'
,
params
=
'hello'
,
query
=
'wb=python&username=abc'
,
fragment
=
'1'
)
通常情況下,使用urlparse和urlsplit是一樣的,唯一不一樣的地方就是,urlparse中間多一個params屬性,而urlsplit沒有這個屬性
request.Request類
如果想要在請求的時候增加一些請求頭,那么就必須使用request.Request來實現。如果要增加一個User-Agent
from
urllib
import
request
url
=
'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='
# resp = request.urlopen(url)
# print(resp.read())
headers
=
{
'User-Agent'
:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
req
=
request
.
Request
(
url
,
headers
=
headers
)
resp
=
request
.
urlopen
(
req
)
print
(
resp
.
read
(
)
)
在上面的代碼中,如果想要給請求的url加上一個請求頭的話,就需要使用request.Request這個方式將請求的內容進行一個封裝,這里封裝的請求頭是User-Agent這個請求頭,這里將這里面的內容寫上瀏覽器的標識;這里需要注意,這里封裝好了之后,是還并沒有發起請求的,最后還是調用的request.urlopen方法發起請求的
注意:這里的這個request.Request方法除了能夠傳遞User-Agent外,還能夠傳遞data和method
如下:
ProxyHandler處理器(代理設置)
很多網站會檢測某一段時間某個ip的訪問次數(通過流量統計,系統日志等),如果訪問次數多的不像正常人,就會禁止這個ip的訪問,所有我們可以設置一些代理服務器,每隔一段時間換一個代理,就算ip被禁止,依然可以換個ip繼續爬取
urllib中通過ProxyHandler來設置使用代理服務器,下面代碼說明如果使用自定義opener來使用代理
from
urllib
import
request
# 未使用代理
# url = 'http://httpbin.org/ip'
#
# resp = request.urlopen(url)
# print(resp.read())
# -----------------------
# 使用代理的
url
=
'http://httpbin.org/ip'
# 1、使用ProxyHandler,傳入代理構建一個handler
handler
=
request
.
ProxyHandler
(
{
'http'
:
'125.110.75.152:9000'
}
)
# 2、使用上面創建的handler構建一個opener
opener
=
request
.
build_opener
(
handler
)
# 3、使用opener去發送一個請求
resp
=
opener
.
open
(
url
)
print
(
resp
.
read
(
)
)
這里需要了解到的就是在使用urlopen的時候,其實也是完成構建一個handler之后再創建了一個opener,最后發起的請求,這個過程只是在openurl中間隱藏了
常用的代理有:
西刺免費代理IP:https://www.xicidaili.com/nt/
快代理:https://www.kuaidaili.com/
代理云:http://www.dailiyun.com/
在需要測試發送請求的機器對應的外網地址,可以使用http://httpbin.org/ip方式獲取
小結
1、代理的原理:在請求目的服務器之前,先請求代理服務器,然后讓代理服務器去請求目的網站,代理服務器拿到目的網站的數據后,再轉發給我們的代碼
2、http://httpbin.org:這個網站可以方便的查看http請求的一些請求
3、在代碼中使用代理:
3.1 使用 urllib.request.ProxyHandler
3.2 傳入一個代理,這個代理是一個字典,字典的key是http或者https,value是ip:port
3.2 使用上一步創建的handler,以及request.build_handler創建一個opener對象
3.3 使用上一步創建的opener,使用open函數,發起請求
什么是cookie
在網站中,http請求是無狀態的,也就是說即使第一次和服務器連接后并且登陸成功后,第二次請求服務器依然不能知道當前是哪個用戶。cookie的出現就是為了解決這個問題,第一次登陸后服務器返回一些數據(cookie)給瀏覽器,然后瀏覽器保存在本地,當該用戶發送第二次請求的時候,就會自動的把上傳請求存儲的cookie數據自動的攜帶給服務器,服務器通過瀏覽器攜帶的數據就能判斷當前用戶是哪個了。cookie存儲的數據量有限,不同的瀏覽器有不同的存儲大小,但一般不操過4KB,因此使用cookie只能存儲一些小量的數據
cookie的格式
Set
-
Cookie
;
NAME
-
VALUE
;
Expires
/
Max
-
age
-
DATE
;
Path
-
PATH
;
Domain
-
DOMAIN_NAME
;
SECURE
參數含義:
NAME:cookie的名字
VALUE:cookie的制
Expires:cookie的過期時間
Path:cookie作用的域名
Domain:cookie作用的域名
SECURE:是否只在https寫一下起作用
下面以訪問百度為例
可以看到,cookie都是放在Response Headers中間的
使用cookielib庫和HTTPCookieProcessor模擬登陸
Cookie是指網站服務器為了辨別用戶身份和進行Session跟蹤,而存儲在用戶用戶瀏覽器上的文本文件,Cookie可以保持登陸信息到用戶下次與服務器的會話
這里講點題外話:
要將byte類型轉為str類型,轉換過程是byte -> decode -> str
要將str類型轉為byte類型,轉換過程是str -> encode -> byte
示例:
以上的方式是通過瀏覽器首先登陸成功之后,在后面頁面訪問的時候,通過Request Header中間獲取到的Cookie,將這個Cookie放在請求頭中間,使用代碼進行訪問
其實這樣的方式還不是最好的,Cookie是服務端發出的,此時還是copy的瀏覽器的Cookie,更好的方式則是通過模擬登陸之后自動保存Cookie,最后攜帶這個Cookie發起后面的請求
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
