urllib
庫
urllib
庫是python中一個(gè)最基本的網(wǎng)絡(luò)請(qǐng)求庫婶肩×昝梗可以模擬瀏覽器的行為被盈,向指定的服務(wù)器發(fā)送一個(gè)請(qǐng)求析孽,并可以保存服務(wù)器返回的數(shù)據(jù)搭伤。
urlopen
在python3的urllib
庫中,所有和網(wǎng)絡(luò)請(qǐng)求相關(guān)的方法袜瞬,都被集成到urllib.request
模塊下怜俐,以下先來看urlopen
函數(shù)的基本使用
from urllib import request
resp = request.urlopen('http://www.baidu.com')# 默認(rèn)是get請(qǐng)求,如果加data邓尤,則變?yōu)閜ost請(qǐng)求
print(resp.readlines())
print(resp.getcode())
實(shí)際上拍鲤,使用瀏覽器訪問百度,右鍵查看源代碼汞扎。你會(huì)發(fā)現(xiàn)殿漠,跟我們剛才打印出來的數(shù)據(jù)是一模一樣的。也就是說佩捞,上面的三行代碼就已經(jīng)幫我們把百度的首頁的全部代碼爬下來得。一個(gè)基本的url請(qǐng)求對(duì)應(yīng)的python代碼真的非常簡(jiǎn)單蕾哟。
以下對(duì)urlopen
函數(shù)進(jìn)行詳細(xì)講解:
- url:請(qǐng)求的url
- data:請(qǐng)求的data一忱,如果設(shè)置了這個(gè)值,那么將變成post請(qǐng)求
- 返回值:返回值是一個(gè)
http.client.HTTPResponse
對(duì)象谭确,這個(gè)對(duì)象是一個(gè)類文件句柄對(duì)象帘营,有read(size),readline逐哈,readlines以及getcode等方法芬迄。
urlretrieve
urlretrieve
函數(shù):
這個(gè)函數(shù)可以方便的將網(wǎng)頁上的一個(gè)文件保存帶本地。以下代碼可以方便將百度的首頁下載到本地:
from urllib import request
resp = request.urlopen('http://www.baidu.com')# 默認(rèn)是get請(qǐng)求昂秃,如果加data禀梳,則變?yōu)閜ost請(qǐng)求
print(resp.readlines())
print(resp.getcode())
request.urlretrieve('http://www.baidu.com','baidu.html')
urlencode
urlencode
函數(shù):
用瀏覽器發(fā)送請(qǐng)求的時(shí)候,如果url中包含了中文或者其他特殊字符肠骆,那么瀏覽器會(huì)自動(dòng)將我們進(jìn)行編碼算途。而如果使用代碼發(fā)送請(qǐng)求,那么就必須手動(dòng)的進(jìn)行編碼蚀腿,這時(shí)候就應(yīng)該使用urlencode
函數(shù)來實(shí)現(xiàn)嘴瓤。urlencode
可以把字典數(shù)據(jù)轉(zhuǎn)換為URL編碼的數(shù)據(jù)。示例代碼如下:
from urllib import parse
data = {'name':'張三','age':18}
ps = parse.urlencode(data)
print(ps)
打印結(jié)果
name=%E5%BC%A0%E4%B8%89&age=18
parse_qs函數(shù)
可以將經(jīng)過編碼后的url參數(shù)進(jìn)行解碼莉钙。示例代碼如下:
from urllib import parse
qs = 'name=%E5%BC%A0%E4%B8%89&age=18'
print(parse.parse_qs(qs))
打印結(jié)果:
{'name': ['張三'], 'age': ['18']}
urlparse和urlsplit
有時(shí)候拿到一個(gè)url廓脆,想要對(duì)這個(gè)url的各個(gè)組成部分進(jìn)行分割,那么這時(shí)候就可以使用urlparse
或是urlsplit
進(jìn)行分割磁玉。示例代碼如下:
from urllib import parse
url = 'http://www.baidu.com?user=liang'
result = parse.urlsplit(url)
print('scheme:',result.scheme)
print('netloc:',result.netloc)
print('path:',result.path)
print('query:',result.query)
打印結(jié)果
scheme: http
netloc: www.baidu.com
path:
query: user=liang
urlsplit
和urlparse
基本上是一模一樣的停忿。唯一不同的是,urlparse里面多了一個(gè)params屬性蜀涨,而urlsplit
沒有這個(gè)params屬性瞎嬉。比如有一個(gè)url為url=‘http"http://www.baidu.com/s;hello?wd=python#1’
蝎毡,那么urlparse
可以獲取到hello,而urlsplit
不可以獲取到氧枣。url中的params也用的比較少沐兵。
request.Request類
如果想要在請(qǐng)求的時(shí)候增加一些請(qǐng)求頭,那么必須使用request.Request
類來實(shí)現(xiàn)便监。比如要增加一個(gè)User-Agent扎谎,示例代碼如下:
from urllib import request
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'}
url = 'http://www.baidu.com'
req = request.Request(url,headers=headers)
resp = request.urlopen(req)
print(resp.read())
ProxyHandler處理器(代理設(shè)置)
很多網(wǎng)站會(huì)檢查某一段時(shí)間某個(gè)ip的訪問次數(shù)(流量統(tǒng)計(jì),系統(tǒng)日志等)烧董,如果訪問次數(shù)多的不像正常人毁靶,它會(huì)禁止這個(gè)ip的訪問。所以我們可以設(shè)置一些代理服務(wù)器逊移,每隔一段時(shí)間換一個(gè)代理预吆,就算ip被禁止,依然可以換個(gè)ip繼續(xù)爬取胳泉。
urllib中通過ProxyHandler來設(shè)置代理服務(wù)器拐叉,下面代碼說明如何使用自定義opener來使用代理
from urllib import request
handler = request.Request({'http':'218.66.161.88:31769'})
opener = request.build_opener(handler)
req = request.Request('http://httpbin.org/ip')
resp = opener.open(req)
print(resp.read())
常用的代理有:
- 西刺免費(fèi)代理:http://www.xicidaili.com/
- 快代理:https://www.kuaidaili.com/
http://www.httpbin.org這個(gè)網(wǎng)站可以方便的查看http請(qǐng)求的一些參數(shù)
cookie
在網(wǎng)站中,http請(qǐng)求是無狀態(tài)的扇商,也就是說即使第一次和服務(wù)器連接后并且登錄成功后凤瘦,第二次請(qǐng)求服務(wù)器依然不能知道當(dāng)前請(qǐng)求是哪個(gè)用戶。cookie的出現(xiàn)就是為了解決這個(gè)問題案铺,第一登錄后服務(wù)器返回一些數(shù)據(jù)(cookie)給瀏覽器蔬芥,然后瀏覽器保存在本地,當(dāng)該用戶發(fā)送第二次請(qǐng)求的時(shí)候控汉,就會(huì)自動(dòng)把上一次請(qǐng)求存儲(chǔ)的cookie數(shù)據(jù)自動(dòng)的攜帶給服務(wù)器笔诵,服務(wù)器通過瀏覽器攜帶的數(shù)據(jù)就能判斷當(dāng)前用戶是哪個(gè)了。cookie存儲(chǔ)的數(shù)據(jù)量是有限的姑子,不同的瀏覽器有不同的存儲(chǔ)大小嗤放,但一般不超過4kB。因此使用cookie只能存儲(chǔ)一些小量的數(shù)據(jù)壁酬。
cookie的格式
Set-Cookie:NAME-VALUE; Expire/Max-age=DATE;Path=Path; Domain=DOMAIN_NAME; SECURE
參數(shù)意義:
- NAME:Cookie的名字
- VALUE:Cookie的值
- Expire:Cookie的過期時(shí)間
- Path:Cookie作用的路徑
- Domain:Cookie作用的域名
- SECURE:是否只在https協(xié)議下起作用
使用cookielib
和HTTPCookieProcesso
r模擬登錄:
cookie是指網(wǎng)站服務(wù)器為了辨別用戶和進(jìn)行session(會(huì)話)跟蹤次酌,而存儲(chǔ)在瀏覽器上的文本文件,cookie可以保持登錄信息到用戶下次與服務(wù)器的會(huì)話舆乔。
這里以人人網(wǎng)為例岳服。人人網(wǎng)中,要訪問某個(gè)人的主頁希俩,必須先登錄才能訪問吊宋,登錄說白了就是要有cookie信息。那么如果我們想要用代碼的方式訪問颜武,就必須要有正確的cookie信息才能訪問璃搜。解決方案有兩種拖吼,第一種是使用瀏覽器訪問,然后將cookie信息復(fù)制下來放到headers中这吻。示例代碼如下:
from urllib import request
headers = {
"User-Agent":'xxxxxxxx',
"Cookie":'yyyyyyyyyyy'
}
url = 'http://www.renren.com/880151247/profile'
req = request.Request(url,headers=headers)
resp = request.urlopen(req)
with open('renren.html','w') as fp:
fp.write(resp.read().decode('utf-8'))
但是每次在訪問需要cookie的頁面都要重瀏覽器中復(fù)制cookie比較麻煩誊役。在python處理cookie却邓,一般通過http.cookiejar
模塊和urllib模塊的HTTPCookieProcessor
處理模塊類一起使用恶导。http.cookiejar
模塊主要作用是提供用于存儲(chǔ)cookie對(duì)象淮摔。而HTTPCookieProcessor
處理器主要作用是處理這些cookie對(duì)象,并構(gòu)建handler對(duì)象
from urllib import request
from http.cookiejar import MozillaCookieJar
cookiejar = MozillaCookieJar('cookie.txt')
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
resp = opener.open('http://httpbin.org/cookies/set?course=abc')
cookiejar.save(ignore_discard=True)
查看生成的cookie.txt
# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file! Do not edit.
httpbin.org FALSE / FALSE course abc