網路請求之urllib網路請求庫
urllib
庫是Python
中一個最基本的網路請求庫。可以模擬瀏覽器的行為,向指定的伺服器傳送一個請求,並可以儲存伺服器返回的資料。
urlopen函式:
在Python3
的urllib
庫中,所有和網路請求相關的方法,都被集到urllib.request
模組下面了,以先來看下urlopen
函式基本的使用:
from urllib import request
resp = request.urlopen('http://www.baidu.com')
print(resp.read())
實際上,使用瀏覽器訪問百度,右鍵檢視原始碼。你會發現,跟我們剛才打印出來的資料是一模一樣的。也就是說,上面的三行程式碼就已經幫我們把百度的首頁的全部程式碼爬下來了。一個基本的url請求對應的python程式碼真的非常簡單。
以下對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}
qs = parse.urlencode(data)
print(qs)
parse_qs函式:
可以將經過編碼後的url引數進行解碼。示例程式碼如下:
from urllib import parse
qs = "name=%E7%88%AC%E8%99%AB%E5%9F%BA%E7%A1%80&greet=hello+world&age=100"
print(parse.parse_qs(qs))
urlparse和urlsplit:
有時候拿到一個url,想要對這個url中的各個組成部分進行分割,那麼這時候就可以使用urlparse
或者是urlsplit
來進行分割。示例程式碼如下:
from urllib import request,parse
url = 'http://www.baidu.com/s?username=zhiliao'
result = parse.urlsplit(url)
# result = parse.urlparse(url)
print('scheme:',result.scheme)
print('netloc:',result.netloc)
print('path:',result.path)
print('query:',result.query)
urlparse
和urlsplit
基本上是一模一樣的。唯一不一樣的地方是,urlparse
裡面多了一個params
屬性,而urlsplit
沒有這個params
屬性。比如有一個url
為:url = 'http://www.baidu.com/s;hello?wd=python&username=abc#1'
,
那麼urlparse
可以獲取到hello
,而urlsplit
不可以獲取到。url
中的params
也用得比較少。
request.Request類:
如果想要在請求的時候增加一些請求頭,那麼就必須使用request.Request
類來實現。比如要增加一個User-Agent
,示例程式碼如下:
from urllib import request
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
}
req = request.Request("http://www.baidu.com/",headers=headers)
resp = request.urlopen(req)
print(resp.read())
實戰爬取拉鉤網:
# 實戰拉鉤網
# url = 'https://www.lagou.com/jobs/list_python?px=default&city=%E5%85%A8%E5%9B%BD'
url = 'https://www.lagou.com/jobs/positionAjax.json?px=default&needAddtionalResult=false'
resp = request.urlopen(url)
print(resp.read())
headers = {
'Referer':'https://www.lagou.com/jobs/list_python?px=default&city=%E5%85%A8%E5%9B%BD',
'User-Agent':'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Mobile Safari/537.36'
}
data = {
'frist':'true',
'pn':1,
'kd':'python'
}
rep = request.Request(url,headers=headers,data=parse.urlencode(data).encode('utf-8'),method='POST')
resp = request.urlopen(rep)
print(resp.read().decode('utf-8'))
ProxyHandler處理器(代理設定)
很多網站會檢測某一段時間某個IP的訪問次數(通過流量統計,系統日誌等),如果訪問次數多的不像正常人,它會禁止這個IP的訪問。
所以我們可以設定一些代理伺服器,每隔一段時間換一個代理,就算IP被禁止,依然可以換個IP繼續爬取。
urllib中通過ProxyHandler來設定使用代理伺服器,下面程式碼說明如何使用自定義opener來使用代理:
from urllib import request
# 這個是沒有使用代理的
# resp = request.urlopen('http://httpbin.org/get')
# print(resp.read().decode("utf-8"))
# 這個是使用了代理的
handler = request.ProxyHandler({"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())
常用的代理有:
- 西刺免費代理IP:http://www.xicidaili.com/
- 快代理:http://www.kuaidaili.com/
- 代理雲:http://www.dailiyun.com/
什麼是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協議下起作用。
使用cookielib庫和HTTPCookieProcessor模擬登入:
Cookie
是指網站伺服器為了辨別使用者身份和進行Session跟蹤,而儲存在使用者瀏覽器上的文字檔案,Cookie
可以保持登入資訊到使用者下次與伺服器的會話。
這裡以人人網為例。人人網中,要訪問某個人的主頁,必須先登入才能訪問,登入說白了就是要有cookie資訊。那麼如果我們想要用程式碼的方式訪問,就必須要有正確的cookie資訊才能訪問。解決方案有兩種,第一種是使用瀏覽器訪問,然後將cookie資訊複製下來,放到headers中。示例程式碼如下:
from urllib import request
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
'Cookie': 'anonymid=jacdwz2x-8bjldx; depovince=GW; _r01_=1; _ga=GA1.2.1455063316.1511436360; _gid=GA1.2.862627163.1511436360; wp=1; JSESSIONID=abczwY8ecd4xz8RJcyP-v; jebecookies=d4497791-9d41-4269-9e2b-3858d4989785|||||; ick_login=884e75d4-f361-4cff-94bb-81fe6c42b220; _de=EA5778F44555C091303554EBBEB4676C696BF75400CE19CC; p=61a3c7d0d4b2d1e991095353f83fa2141; first_login_flag=1; [email protected]; ln_hurl=http://hdn.xnimg.cn/photos/hdn121/20170428/1700/main_nhiB_aebd0000854a1986.jpg; t=3dd84a3117737e819dd2c32f1cdb91d01; societyguester=3dd84a3117737e819dd2c32f1cdb91d01; id=443362311; xnsid=169efdc0; loginfrom=syshome; ch_id=10016; jebe_key=9c062f5a-4335-4a91-bf7a-970f8b86a64e%7Ca022c303305d1b2ab6b5089643e4b5de%7C1511449232839%7C1; wp_fold=0'
}
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的頁面都要從瀏覽器中複製cookie比較麻煩。在Python處理Cookie,一般是通過http.cookiejar
模組和urllib模組的HTTPCookieProcessor
處理器類一起使用。http.cookiejar
模組主要作用是提供用於儲存cookie的物件。而HTTPCookieProcessor
處理器主要作用是處理這些cookie物件,並構建handler物件。
http.cookiejar模組:
該模組主要的類有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。這四個類的作用分別如下:
- CookieJar:管理HTTP cookie值、儲存HTTP請求生成的cookie、向傳出的HTTP請求新增cookie的物件。整個cookie都儲存在記憶體中,對CookieJar例項進行垃圾回收後cookie也將丟失。
- FileCookieJar (filename,delayload=None,policy=None):從CookieJar派生而來,用來建立FileCookieJar例項,檢索cookie資訊並將cookie儲存到檔案中。filename是儲存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例項。
實戰登入人人網:
利用http.cookiejar
和request.HTTPCookieProcessor
登入人人網。相關示例程式碼如下:
from urllib import request,parse
from http.cookiejar import CookieJar
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
}
def get_opener():
cookiejar = CookieJar()
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
return opener
def login_renren(opener):
data = {"email": "[email protected]", "password": "pythonspider"}
data = parse.urlencode(data).encode('utf-8')
login_url = "http://www.renren.com/PLogin.do"
req = request.Request(login_url, headers=headers, data=data)
opener.open(req)
def visit_profile(opener):
url = 'http://www.renren.com/880151247/profile'
req = request.Request(url,headers=headers)
resp = opener.open(req)
with open('renren.html','w') as fp:
fp.write(resp.read().decode("utf-8"))
if __name__ == '__main__':
opener = get_opener()
login_renren(opener)
visit_profile(opener)
儲存cookie到本地:
儲存cookie
到本地,可以使用cookiejar
的save
方法,並且需要指定一個檔名:
from urllib import request
from http.cookiejar import MozillaCookieJar
cookiejar = MozillaCookieJar("cookie.txt")
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
}
req = request.Request('http://httpbin.org/cookies',headers=headers)
resp = opener.open(req)
print(resp.read())
cookiejar.save(ignore_discard=True,ignore_expires=True)
從本地載入cookie:
從本地載入cookie
,需要使用cookiejar
的load
方法,並且也需要指定方法:
from urllib import request
from http.cookiejar import MozillaCookieJar
cookiejar = MozillaCookieJar("cookie.txt")
cookiejar.load(ignore_expires=True,ignore_discard=True)
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'
}
req = request.Request('http://httpbin.org/cookies',headers=headers)
resp = opener.open(req)
print(resp.read())
更多Python實戰原始碼請關注 朝南而行 公眾號
上一篇:什麼是http和https協議
下一篇:資料解析之XPath語法和lxml模組