二、學習分佈式爬蟲之urllib庫

urllib庫(python自帶)

urllib庫是python中一個基本的網絡請求庫,可以模擬瀏覽器行爲,向指定的服務器發送請求,並可以保存服務器返回的數據。
python3的urllib庫中所有和網絡請求相關的方法,都被集到urllib.request模塊中

urlopen函數

創建一個表示遠程url的類文件對象,然後像本地文件一樣操作這個類文件對象來獲取遠程數據。(瀏覽器打開網址)

  1. url:請求的網址
  2. data:請求的數據,如果設置了這個值,那麼將變成post請求。
  3. 返回值:返回值是一個<http.client.HTTPResponse object at 0x0338FDC0>對象,有read(size),readline(),readlines()以及getcode()(獲取狀態碼)等方法。
from urllib import request
resp = request.urlopen('https://www.sogou.com/')
print(resp.read())

urlretrieve函數

這個函數可以方便的將網頁上的一個文件保存到本地

from urllib import request
request.urlretrieve('https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1449833412,3131219507&fm=26&gp=0.jpg','周杰倫.jpg')

urlencode函數

可以把字典數據轉換爲URL編碼的數據

from urllib import parse
data = {'name':'周杰倫','age':'30','greet':'hello world'}
res = parse.urlencode(data) #編碼
print(res)# name=%E5%91%A8%E6%9D%B0%E4%BC%A6&age=30&greet=hello+world
res_de=parse.parse_qs(res) #解碼
print(res_de)
#{'name': ['周杰倫'], 'age': ['30'], 'greet': ['hello world']}

parse.quote():可以對字符串進行編碼

url解析

有時候拿到一個url,想要對這個url中的各個組成部分進行分割,就可以使用urlparse和urlsplit函數。
兩個函數基本上是一樣的,唯一不一樣的地方就是urlparse裏有params屬性,而urlsplit沒有。

from urllib import parse
res = parse.urlparse('http://www.baidu.com/index.html;user?id=s#comment')
#ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=s', fragment='comment')
print(res)
print(res.scheme)
print(res.netloc)
print(res.path)
from urllib import parse
res = parse.urlsplit('http://www.baidu.com/index.html;user?id=s#comment')
#SplitResult(scheme='http', netloc='www.baidu.com', path='/index.html;user', query='id=s', fragment='comment')
print(res)
print(res.scheme)
print(res.netloc)
print(res.path)

request.Request類:網絡請求,可以增加請求頭

from urllib import request
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'
}
res = request.Request('https://www.baidu.com/',headers=header)
resp = request.urlopen(res)
print(resp.read())

proxyHandler處理器(代理設置):解決封IP問題

很多網站會檢測某段時間某個IP的訪問次數(通過流量統計、系統日誌等),如果訪問次數多的不像正常人,它會禁止這個IP的訪問。
http://httpbin.org 查看http請求的一些參數。
常用的代理

  1. 西刺免費代理IP:http://www.xicidaili.com/
  2. 快代理:http://www.kuaidaili.com/
  3. 代理雲:http://www.dailiyun.com/
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':'115.216.56.155:9999'})
#2.使用上面的handler構建一個opener
opener = request.build_opener(handler)
#3.使用opener發送一個請求
resp = opener.open(url)
print(resp.read())

什麼是cookie

指某些網站爲了辨別用戶身份進行session跟蹤而儲存在用戶本都終端上的數據,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協議下起作用

知乎登錄模擬實戰1

from urllib import request
url = 'https://www.zhihu.com/'
header = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36',
    #添加cookie
    'cookie': '_zap=d787f891-928e-4802-a36f-f932fbce85cc; _xsrf=T4pgZdazbwlWX70ktyxjai6mBHqt2Tee; d_c0="ADAXHRmRyhCPTnOLCXOeSw2YPn2xT_iZvq8=|1581251934"; capsion_ticket="2|1:0|10:1581251957|14:capsion_ticket|44:Njg1OTQxMWQ5YzkzNGEzMThlMjRiYzA3YjlhYWE3Y2I=|5b514ab39e5c847c527eb6d6967cfa29a2dc1cab5056f490d155c25c78b79c90"; z_c0="2|1:0|10:1581251999|4:z_c0|92:Mi4xTmd6VkNnQUFBQUFBTUJjZEdaSEtFQ1lBQUFCZ0FsVk5uMHN0WHdCOGs3MmZOTkdfT21lRVlCSUQwY1V6cFN5N09n|3cc13f09f49f1de5535017656d99fe7f4ce2ca4dc239911a9ac866f7f2110f8d"; unlock_ticket="APDltcvN3A0mAAAAYAJVTacEQF4avQyXNCvlitZvRoXJOoaaF1rJ0g=="; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1581252005; tst=r; KLBRSID=4843ceb2c0de43091e0ff7c22eadca8c|1581252069|1581251924; Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49=1581252069'
}
resp = request.Request(url,headers=header)
res = request.urlopen(resp)
print(res.read().decode('utf-8'))

http.cookiejar模塊

該模塊主要的類有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。作用分別如下:

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

美食傑模擬登錄爬取個人網頁信息

from urllib import request
from urllib import parse
from http.cookiejar import CookieJar

#登錄的網頁 https://i.meishi.cc/login.php
#個人網頁  https://i.meishi.cc/cook.php?id=14417636

#1.登錄
#1.1  創建cookiejar對象
cookiejar = CookieJar()
#1.2  使用cookiejar對象創建一個HTTPCookieProcess對象
handler = request.HTTPCookieProcessor(cookiejar)
#1.3  使用上一步創建的handler創建一個opener
opener = request.build_opener(handler)
#1.4  使用opener發送登錄請求  (需要賬號和密碼)
post_url = 'https://i.meishi.cc/login.php'
post_data = parse.urlencode({
    'username':'1579795****',
    'password':'****'
})#需要對賬戶和密碼進行url編碼
req = request.Request(post_url,data=post_data.encode('utf-8'))  #獲得一個urllib.request.Request object
opener.open(req) #運行後opener會擁有登錄所需要的cookie

#2. 訪問個人網頁
header = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36'
}
url = 'https://i.meishi.cc/cook.php?id=14417636'
rq = request.Request(url,headers=header)
res = opener.open(rq) #此時opener已經擁有登錄所需要的cookie
print(res.read().decode('utf-8'))

cookie的保存與加載

from urllib import request
from http.cookiejar import MozillaCookieJar

#將cookie保存到本地
cookiejar = MozillaCookieJar('cookie.txt')
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
res = opener.open('http://www.baidu.com')
cookiejar.save(ignore_discard=True,ignore_expires=True)
#ignore_discard當cookie即將過期,False不將它保存,True則仍保存
#ignore_expires當cookie已經過期,False不將它保存,True則仍保存

#加載cookie
cookiejar = MozillaCookieJar('cookie.txt')
cookiejar.load()
handler = request.HTTPCookieProcessor(cookiejar)
opener = request.build_opener(handler)
res = opener.open('http://www.baidu.com')
for cookie in cookiejar:
    print(cookie)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章