目錄
1.使用urllib來(lái)獲取百度首頁(yè)的源碼
2.下載網(wǎng)頁(yè)圖片視頻
?3.總結(jié)-1
4.請(qǐng)求對(duì)象的定制(解決第一種反爬)
? 5.編解碼
(1)get請(qǐng)求方式:urllib.parse.quote()
(2)get請(qǐng)求方式:urllib.parse.urlencode()
(3)post請(qǐng)求方式
6.ajax的get請(qǐng)求
(1)獲取豆瓣電影的第一頁(yè)的數(shù)據(jù)
(2)下載豆瓣電影前10頁(yè)的數(shù)據(jù)
7.ajax的post請(qǐng)求
8.異常? URLError\HTTPError
9.cookie登錄(cookie反爬)
10.Handler處理器
11.代理服務(wù)器
1.使用urllib來(lái)獲取百度首頁(yè)的源碼
代碼
#使用urllib來(lái)獲取百度首頁(yè)的源碼
import urllib.request
#(1)定義一個(gè)url就是你要訪問(wèn)的地址
url = 'http: // www. baidu.com'
#(2)模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求response響應(yīng)
response = urllib.request.urlopen(url)
#(3)獲取響應(yīng)中的頁(yè)面的源碼content內(nèi)容的意思
# read方法返回的是字節(jié)形式的二進(jìn)制數(shù)據(jù)
#我們要將二進(jìn)制的數(shù)據(jù)轉(zhuǎn)換為字符串
#二進(jìn)制--》字符串解碼decode('編碼的格式')
content = response.read().decode('utf-8')
#(4)打印數(shù)據(jù)
print(content)
運(yùn)行結(jié)果
2.下載網(wǎng)頁(yè)圖片視頻
urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)
函數(shù)說(shuō)明
將URL表示的網(wǎng)絡(luò)對(duì)象復(fù)制到本地文件。如果URL指向本地文件,則對(duì)象將不會(huì)被復(fù)制,除非提供文件名。返回一個(gè)元組()(filename,header),其中filename是可以找到對(duì)象的本地文件名,header是urlopen()返回的對(duì)象的info()方法(用于遠(yuǎn)程對(duì)象)。
第二個(gè)參數(shù)(如果存在)指定要復(fù)制到的文件位置(如果沒(méi)有,該位置將是一個(gè)生成名稱的tempfile)。第三個(gè)參數(shù),如果存在,則是一個(gè)回調(diào)函數(shù),它將在建立網(wǎng)絡(luò)連接時(shí)調(diào)用一次,并且在此后每個(gè)塊讀取后調(diào)用一次。這個(gè)回調(diào)函數(shù)將傳遞三個(gè)參數(shù);到目前為止傳輸?shù)膲K計(jì)數(shù),以字節(jié)為單位的塊大小,以及文件的總大小。第三個(gè)參數(shù)可能是-1,在舊的FTP服務(wù)器上,它不返回文件大小以響應(yīng)檢索請(qǐng)求。參數(shù)說(shuō)明
url:外部或者本地url
filename:指定了保存到本地的路徑(如果未指定該參數(shù),urllib會(huì)生成一個(gè)臨時(shí)文件來(lái)保存數(shù)據(jù));reporthook:是一個(gè)回調(diào)函數(shù),當(dāng)連接上服務(wù)器、以及相應(yīng)的數(shù)據(jù)塊傳輸完畢的時(shí)候會(huì)觸發(fā)該回調(diào)。我們可以利用這個(gè)回調(diào)函數(shù)來(lái)顯示當(dāng)前的下載進(jìn)度。
data:指post到服務(wù)器的數(shù)據(jù)。該方法返回一個(gè)包含兩個(gè)元素的元組(filename, headers),filename表示保存到本地的路徑,header表示服務(wù)器的響應(yīng)頭。
?
import urllib.request
# 下載網(wǎng)頁(yè)
url_page = 'http://www.baidu.com'
# url代表的是下載的路徑 filename文件的名字
# 在python中 可以變量的名字 也可以直接寫值
urllib.request.urlretrieve(url_page,'baidu.html')
# 下載圖片
url_img = 'https://img1.baidu.com/it/u=3004965690,4089234593&fm=26&fmt=auto&gp=0.jpg'
urllib.request.urlretrieve(url= url_img,filename='lisa.jpg')
# 下載視頻
url_video = 'https://vd3.bdstatic.com/mda-mhkku4ndaka5etk3/1080p/cae_h264/1629557146541497769/mda-mhkku4ndaka5etk3.mp4?v_from_s=hkapp-haokan-tucheng&auth_key=1629687514-0-0-7ed57ed7d1168bb1f06d18a4ea214300&bcevod_channel=searchbox_feed&pd=1&pt=3&abtest='
urllib.request.urlretrieve(url_video,'hxekyyds.mp4')
?3.總結(jié)-1
- urllib.request.urlopen()???????? 模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求
- response ????????服務(wù)器返回的數(shù)據(jù)
- response的數(shù)據(jù)類型是HttpResponse
- 字節(jié)‐‐>字符串 解碼????????decode
- 字符串‐‐>字節(jié) 編碼????????encode
- read() ????????字節(jié)形式讀取二進(jìn)制? ? 擴(kuò)展:read(5)返回前五個(gè)字節(jié)
- readline() ????????讀取一行
- readlines() ????????一行一行讀取 直至結(jié)束
- getcode() ????????獲取狀態(tài)碼,是200的話表示狀態(tài)正常,還可能為404等等
- geturl() ????????獲取訪問(wèn)的url地址
- getheaders() ????????獲取headers狀態(tài)信息,響應(yīng)頭
- urllib.request.urlretrieve() ????????請(qǐng)求網(wǎng)頁(yè) 請(qǐng)求圖片 請(qǐng)求視頻
- 運(yùn)行框中通過(guò) Ctrl+f 來(lái)進(jìn)行搜索內(nèi)容
4.請(qǐng)求對(duì)象的定制(解決第一種反爬)
UA介紹:User Agent中文名為用戶代理,簡(jiǎn)稱 UA,它是一個(gè)特殊字符串頭,使得服務(wù)器能夠識(shí)別客戶使用的操作系統(tǒng) 及版本、CPU 類型、瀏覽器及版本。瀏覽器內(nèi)核、瀏覽器渲染引擎、瀏覽器語(yǔ)言、瀏覽器插件等
語(yǔ)法:request = urllib.request.Request()
import urllib.request
url = 'https://www.baidu.com'
# url的組成
# https://www.baidu.com/s?wd=周杰倫
# http/https www.baidu.com 80/443 s wd = 周杰倫 #
# 協(xié)議 主機(jī) 端口號(hào) 路徑 參數(shù) 錨點(diǎn)
# http 80
# https 443
# mysql 3306
# oracle 1521
# redis 6379
# mongodb 27017
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
# 因?yàn)閡rlopen方法中不能存儲(chǔ)字典 所以headers不能傳遞進(jìn)去
# 請(qǐng)求對(duì)象的定制
# 注意因?yàn)閰?shù)順序的問(wèn)題﹐不能直接寫url 和headers中間還有data所以我們需要關(guān)鍵字傳參
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf8')
print(content)
? 5.編解碼
'''編碼集的演變‐‐‐'''
由于計(jì)算機(jī)是美國(guó)人發(fā)明的,因此,最早只有127個(gè)字符被編碼到計(jì)算機(jī)里,也就是大小寫英文字母、數(shù)字和一些符號(hào), 這個(gè)編碼表被稱為ASCII編碼,比如大寫字母A的編碼是65,小寫字母z的編碼是122。 但是要處理中文顯然一個(gè)字節(jié)是不夠的,至少需要兩個(gè)字節(jié),而且還不能和ASCII編碼沖突, 所以,中國(guó)制定了GB2312編碼,用來(lái)把中文編進(jìn)去。 你可以想得到的是,全世界有上百種語(yǔ)言,日本把日文編到Shift_JIS里,韓國(guó)把韓文編到Euc‐kr里, 各國(guó)有各國(guó)的標(biāo)準(zhǔn),就會(huì)不可避免地出現(xiàn)沖突,結(jié)果就是,在多語(yǔ)言混合的文本中,顯示出來(lái)會(huì)有亂碼。 因此,Unicode應(yīng)運(yùn)而生。Unicode把所有語(yǔ)言都統(tǒng)一到一套編碼里,這樣就不會(huì)再有亂碼問(wèn)題了。 Unicode標(biāo)準(zhǔn)也在不斷發(fā)展,但最常用的是用兩個(gè)字節(jié)表示一個(gè)字符(如果要用到非常偏僻的字符,就需要4個(gè)字節(jié))。 現(xiàn)代操作系統(tǒng)和大多數(shù)編程語(yǔ)言都直接支持Unicode。
(1)get請(qǐng)求方式:urllib.parse.quote()
quote函數(shù),用于將字符串進(jìn)行編碼以便于復(fù)制到瀏覽器或向服務(wù)器發(fā)送請(qǐng)求。
# https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
# 需求 獲取 https://www.baidu.com/s?wd=周杰倫的網(wǎng)頁(yè)源碼
import urllib.request
import urllib.parse
# 直接在這里打上周杰倫會(huì)報(bào)錯(cuò),因?yàn)锳SCII碼無(wú)法識(shí)別中文
url = 'https://www.baidu.com/s?wd='
# 請(qǐng)求對(duì)象的定制為了解決反爬的第一種手段
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
# 將周杰倫三個(gè)字變成unicode編碼的格式
# 我們需要依賴于urllib.parse
name = urllib.parse.quote('周杰倫')
url = url + name
# 請(qǐng)求對(duì)象的定制
request = urllib.request.Request(url=url,headers=headers)
# 模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求
response = urllib.request.urlopen(request)
# 獲取響應(yīng)的內(nèi)容
content = response.read().decode('utf-8')
# 打印數(shù)據(jù)
print(content)
eg:
import urllib.requestimport urllib.parse
url = 'https : / /www . baidu.com/s ?wd='
headers = {'User-Agent ' : 'Mozilla/5.0 (Windows NT 10.0; win64; x64) ApplelebKit/537.36 (KHTML,likeGecko) chrome/74.8.3729.169 Safari/537.36'}
url = url + urllib.parse.quote( '小野')
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen( request)
print(response.read( ).decode( 'utf-8'))
?
(2)get請(qǐng)求方式:urllib.parse.urlencode()
- 傳入?yún)?shù)類型:字典
- 功能:將存入的字典參數(shù)編碼為URL查詢字符串,即轉(zhuǎn)換成以key1=value1&key2=value2的形式
# urlencode應(yīng)用場(chǎng)景:多個(gè)參數(shù)的時(shí)候
# https://www.baidu.com/s?wd=周杰倫&sex=男
#獲取https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6&sex=%E7%94%B7的網(wǎng)頁(yè)源碼
import urllib.request
import urllib.parse
base_url = 'https://www.baidu.com/s?'
data = {
'wd':'周杰倫',
'sex':'男',
'location':'中國(guó)臺(tái)灣省'
}
new_data = urllib.parse.urlencode(data)
# 請(qǐng)求資源路徑
url = base_url + new_data
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
# 請(qǐng)求對(duì)象的定制
request = urllib.request.Request(url=url,headers=headers)
# 模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求
response = urllib.request.urlopen(request)
# 獲取網(wǎng)頁(yè)源碼的數(shù)據(jù)
content = response.read().decode('utf-8')
# 打印數(shù)據(jù)
print(content)
eg:
import urllib.requestimport urllib.parse
url = 'http : / /www . baidu.com/s?'data = {
????????'name ' : '小剛',????????'sex':'男',
}
data = urllib.parse.urlencode(data)url = url + data
print(url)
headers = {
'User-Agent ' : 'Nozilla/5.0 (Windows NT 10.0; win64; x64)ApplewebKit/537.36 (KHTML,likeGecko) Chrome/74.0.3729.169 Safari/537.36'
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen( request)
print(response.read( ).decode( '?utf-8 '))
(3)post請(qǐng)求方式
對(duì)于需要傳入的data 數(shù)據(jù),需要進(jìn)行urlencode編碼。postdata=urllib.parse.urlencode(data).encode('utf-8')
# post請(qǐng)求
import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/sug'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
data = {
'kw':'spider'
}
# post請(qǐng)求的參數(shù) 必須要進(jìn)行編碼
data = urllib.parse.urlencode(data).encode('utf-8')
# post的請(qǐng)求的參數(shù) 是不會(huì)拼接在url的后面的 而是需要放在請(qǐng)求對(duì)象定制的data參數(shù)中
# post請(qǐng)求的參數(shù) 必須要進(jìn)行編碼
request = urllib.request.Request(url=url,data=data,headers=headers)
# 模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求
response = urllib.request.urlopen(request)
# 獲取響應(yīng)的數(shù)據(jù)
content = response.read().decode('utf-8')
# 字符串--》json對(duì)象
import json
obj = json.loads(content)
print(obj)
# post請(qǐng)求方式的參數(shù) 必須編碼 data = urllib.parse.urlencode(data)
# 編碼之后 必須調(diào)用encode方法 data = urllib.parse.urlencode(data).encode('utf-8')
# 參數(shù)是放在請(qǐng)求對(duì)象定制的方法中 request = urllib.request.Request(url=url,data=data,headers=headers)
?總結(jié):post和get區(qū)別
1:get請(qǐng)求方式的參數(shù)必須編碼,參數(shù)是拼接到url后面,編碼之后不需要調(diào)用encode方法 2:post請(qǐng)求方式的參數(shù)必須編碼,參數(shù)是放在請(qǐng)求對(duì)象定制的方法中,編碼之后需要調(diào)用encode方法
import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/v2transapi?from=en&to=zh'
headers = {
# 'Accept': '*/*',
# 'Accept-Encoding': 'gzip, deflate, br',
# 'Accept-Language': 'zh-CN,zh;q=0.9',
# 'Connection': 'keep-alive',
# 'Content-Length': '135',
# 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': 'BIDUPSID=DAA8F9F0BD801A2929D96D69CF7EBF50; PSTM=1597202227; BAIDUID=DAA8F9F0BD801A29B2813502000BF8E9:SL=0:NR=10:FG=1; __yjs_duid=1_c19765bd685fa6fa12c2853fc392f8db1618999058029; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BDUSS=R2bEZvTjFCNHQxdUV-cTZ-MzZrSGxhbUYwSkRkUWk2SkxxS3E2M2lqaFRLUlJoRVFBQUFBJCQAAAAAAAAAAAEAAAA3e~BTveK-9sHLZGF5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFOc7GBTnOxgaW; BDUSS_BFESS=R2bEZvTjFCNHQxdUV-cTZ-MzZrSGxhbUYwSkRkUWk2SkxxS3E2M2lqaFRLUlJoRVFBQUFBJCQAAAAAAAAAAAEAAAA3e~BTveK-9sHLZGF5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFOc7GBTnOxgaW; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BAIDUID_BFESS=DAA8F9F0BD801A29B2813502000BF8E9:SL=0:NR=10:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=2; H_PS_PSSID=34435_31660_34405_34004_34073_34092_26350_34426_34323_22158_34390; delPer=1; BA_HECTOR=8185a12020018421b61gi6ka20q; BCLID=10943521300863382545; BDSFRCVID=boDOJexroG0YyvRHKn7hh7zlD_weG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0mOTHv8F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tR3aQ5rtKRTffjrnhPF3-44vXP6-hnjy3bRkX4Q4Wpv_Mnndjn6SQh4Wbttf5q3RymJ42-39LPO2hpRjyxv4y4Ldj4oxJpOJ-bCL0p5aHl51fbbvbURvD-ug3-7qqU5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-jBRIE3-oJqC8hMIt43f; BCLID_BFESS=10943521300863382545; BDSFRCVID_BFESS=boDOJexroG0YyvRHKn7hh7zlD_weG7bTDYLEOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKK0mOTHv8F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tR3aQ5rtKRTffjrnhPF3-44vXP6-hnjy3bRkX4Q4Wpv_Mnndjn6SQh4Wbttf5q3RymJ42-39LPO2hpRjyxv4y4Ldj4oxJpOJ-bCL0p5aHl51fbbvbURvD-ug3-7qqU5dtjTO2bc_5KnlfMQ_bf--QfbQ0hOhqP-jBRIE3-oJqC8hMIt43f; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1629701482,1629702031,1629702343,1629704515; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1629704515; __yjs_st=2_MDBkZDdkNzg4YzYyZGU2NTM5NzBjZmQ0OTZiMWRmZGUxM2QwYzkwZTc2NTZmMmIxNDJkYzk4NzU1ZDUzN2U3Yjc4ZTJmYjE1YTUzMTljYWFkMWUwYmVmZGEzNmZjN2FlY2M3NDAzOThhZTY5NzI0MjVkMmQ0NWU3MWE1YTJmNGE5NDBhYjVlOWY3MTFiMWNjYTVhYWI0YThlMDVjODBkNWU2NjMwMzY2MjFhZDNkMzVhNGMzMGZkMWY2NjU5YzkxMDk3NTEzODJiZWUyMjEyYTk5YzY4ODUyYzNjZTJjMGM5MzhhMWE5YjU3NTM3NWZiOWQxNmU3MDVkODExYzFjN183XzliY2RhYjgz; ab_sr=1.0.1_ZTc2ZDFkMTU5ZTM0ZTM4MWVlNDU2MGEzYTM4MzZiY2I2MDIxNzY1Nzc1OWZjZGNiZWRhYjU5ZjYwZmNjMTE2ZjIzNmQxMTdiMzIzYTgzZjVjMTY0ZjM1YjMwZTdjMjhiNDRmN2QzMjMwNWRhZmUxYTJjZjZhNTViMGM2ODFlYjE5YTlmMWRjZDAwZGFmMDY4ZTFlNGJiZjU5YzE1MGIxN2FiYTU3NDgzZmI4MDdhMDM5NTQ0MjQxNDBiNzdhMDdl',
# 'Host': 'fanyi.baidu.com',
# 'Origin': 'https://fanyi.baidu.com',
# 'Referer': 'https://fanyi.baidu.com/?aldtype=16047',
# 'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
# 'sec-ch-ua-mobile': '?0',
# 'Sec-Fetch-Dest': 'empty',
# 'Sec-Fetch-Mode': 'cors',
# 'Sec-Fetch-Site': 'same-origin',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
# 'X-Requested-With': 'XMLHttpRequest',
}
data = {
'from': 'en',
'to': 'zh',
'query': 'love',
'transtype': 'realtime',
'simple_means_flag': '3',
'sign': '198772.518981',
'token': '5483bfa652979b41f9c90d91f3de875d',
'domain': 'common',
}
# post請(qǐng)求的參數(shù) 必須進(jìn)行編碼 并且要調(diào)用encode方法
data = urllib.parse.urlencode(data).encode('utf-8')
# 請(qǐng)求對(duì)象的定制
request = urllib.request.Request(url = url,data = data,headers = headers)
# 模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求
response = urllib.request.urlopen(request)
# 獲取響應(yīng)的數(shù)據(jù)
content = response.read().decode('utf-8')
# loads將字符串轉(zhuǎn)換為python對(duì)象
import json
obj = json.loads(content)
print(obj)
# python對(duì)象轉(zhuǎn)換為json字符串 ensure_ascii=False 忽略字符集編碼
s = json.dumps(obj,ensure_ascii=False)
print(s)
6.ajax的get請(qǐng)求
(1)獲取豆瓣電影的第一頁(yè)的數(shù)據(jù)
# get請(qǐng)求
# 獲取豆瓣電影的第一頁(yè)的數(shù)據(jù) 并且保存起來(lái)
import urllib.request
url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
# (1) 請(qǐng)求對(duì)象的定制
request = urllib.request.Request(url=url,headers=headers)
# (2)獲取響應(yīng)的數(shù)據(jù)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
# (3) 數(shù)據(jù)下載到本地
# open方法默認(rèn)情況下使用的是gbk的編碼 如果我們要想保存漢字 那么需要在open方法中指定編碼格式為utf-8
# encoding = 'utf-8'
# fp = open('douban.json','w',encoding='utf-8')
# fp.write(content)
with open('douban1.json','w',encoding='utf-8') as fp:
fp.write(content)
(2)下載豆瓣電影前10頁(yè)的數(shù)據(jù)
# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=0&limit=20
# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=20&limit=20
# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=40&limit=20
# https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&
# start=60&limit=20
# page 1 2 3 4
# start 0 20 40 60
# start (page - 1)*20
# 下載豆瓣電影前10頁(yè)的數(shù)據(jù)
# (1) 請(qǐng)求對(duì)象的定制
# (2) 獲取響應(yīng)的數(shù)據(jù)
# (3) 下載數(shù)據(jù)
import urllib.parse
import urllib.request
# 每執(zhí)行一次返回一個(gè)request對(duì)象
def create_request(page):
base_url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&'
data = {
'start':(page - 1) * 20,
'limit':20
}
# data編碼
data = urllib.parse.urlencode(data)
url = base_url + data
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
request = urllib.request.Request(url=url,headers=headers)
return request
# 獲取網(wǎng)頁(yè)源碼
def get_content(request):
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
return content
def down_load(page,content):
with open('douban_' + str(page) + '.json','w',encoding='utf-8')as fp:
fp.write(content)
# 程序的入口
if __name__ == '__main__':
start_page = int(input('請(qǐng)輸入起始的頁(yè)碼'))
end_page = int(input('請(qǐng)輸入結(jié)束的頁(yè)面'))
for page in range(start_page,end_page+1):
# 每一頁(yè)都有自己的請(qǐng)求對(duì)象的定制
request = create_request(page)
# 獲取響應(yīng)的數(shù)據(jù)
content = get_content(request)
# 下載
down_load(page,content)
7.ajax的post請(qǐng)求
# 1頁(yè)
# http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# post
# cname: 北京
# pid:
# pageIndex: 1
# pageSize: 10
# 2頁(yè)
# http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname
# post
# cname: 北京
# pid:
# pageIndex: 2
# pageSize: 10
import urllib.request
import urllib.parse
def create_request(page):
base_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'
data = {
'cname': '北京',
'pid':'',
'pageIndex': page,
'pageSize': '10'
}
data = urllib.parse.urlencode(data).encode('utf-8')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
request = urllib.request.Request(url=base_url,headers=headers,data=data)
return request
def get_content(request):
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
return content
def down_load(page,content):
with open('kfc_' + str(page) + '.json','w',encoding='utf-8')as fp:
fp.write(content)
if __name__ == '__main__':
start_page = int(input('請(qǐng)輸入起始頁(yè)碼'))
end_page = int(input('請(qǐng)輸入結(jié)束頁(yè)碼'))
for page in range(start_page,end_page+1):
# 請(qǐng)求對(duì)象的定制
request = create_request(page)
# 獲取網(wǎng)頁(yè)源碼
content = get_content(request)
# 下載
down_load(page,content)
8.異常? URLError\HTTPError
簡(jiǎn)介:
- HTTPError類是URLError類的子類
- 導(dǎo)入的包urllib.error.HTTPError? ? urllib.error.URLError
- http錯(cuò)誤:http錯(cuò)誤是針對(duì)瀏覽器無(wú)法連接到服務(wù)器而增加出來(lái)的錯(cuò)誤提示。引導(dǎo)并告訴瀏覽者該頁(yè)是哪里出 了問(wèn)題。
- 通過(guò)urllib發(fā)送請(qǐng)求的時(shí)候,有可能會(huì)發(fā)送失敗,這個(gè)時(shí)候如果想讓你的代碼更加的健壯,可以通過(guò)try‐ except進(jìn)行捕獲異常,異常有兩類,URLError\HTTPError
import urllib.request
import urllib.error
# url = 'https://blog.csdn.net/sulixu/article/details/1198189491'
url = 'http://www.doudan1111.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
try:
request = urllib.request.Request(url = url, headers = headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
print(content)
except urllib.error.HTTPError:
print('系統(tǒng)正在升級(jí)。。。')
except urllib.error.URLError:
print('我都說(shuō)了 系統(tǒng)正在升級(jí)。。。')
9.cookie登錄(cookie反爬)
使用連接訪問(wèn)微博的一個(gè)頁(yè)面時(shí),會(huì)先跳轉(zhuǎn)到登錄界面,如果直接爬取頁(yè)面會(huì)報(bào)如下錯(cuò)誤
- 適用的場(chǎng)景:數(shù)據(jù)采集的時(shí)候 需要繞過(guò)登陸 然后進(jìn)入到某個(gè)頁(yè)面
- 個(gè)人信息頁(yè)面是utf-8 ?但是還報(bào)錯(cuò)了編碼錯(cuò)誤 ?因?yàn)椴](méi)有進(jìn)入到個(gè)人信息頁(yè)面 而是跳轉(zhuǎn)到了登陸頁(yè)面,而登陸頁(yè)面不是utf-8 ?所以報(bào)錯(cuò)
- 什么情況下訪問(wèn)不成功?# 因?yàn)檎?qǐng)求頭的信息不夠 ?所以訪問(wèn)不成功
# 適用的場(chǎng)景:數(shù)據(jù)采集的時(shí)候 需要繞過(guò)登陸 然后進(jìn)入到某個(gè)頁(yè)面
# 個(gè)人信息頁(yè)面是utf-8 但是還報(bào)錯(cuò)了編碼錯(cuò)誤 因?yàn)椴](méi)有進(jìn)入到個(gè)人信息頁(yè)面 而是跳轉(zhuǎn)到了登陸頁(yè)面
# 那么登陸頁(yè)面不是utf-8 所以報(bào)錯(cuò)
# 什么情況下訪問(wèn)不成功?
# 因?yàn)檎?qǐng)求頭的信息不夠 所以訪問(wèn)不成功
import urllib.request
url = 'https://weibo.cn/6451491586/info'
headers = {
# ':authority': 'weibo.cn',
# ':method': 'GET',
# ':path': '/6451491586/info',
# ':scheme': 'https',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
# 'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'max-age=0',
# cookie中攜帶著你的登陸信息 如果有登陸之后的cookie 那么我們就可以攜帶著cookie進(jìn)入到任何頁(yè)面
'cookie': '_T_WM=24c44910ba98d188fced94ba0da5960e; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WFxxfgNNUmXi4YiaYZKr_J_5NHD95QcSh-pSh.pSKncWs4DqcjiqgSXIgvVPcpD; SUB=_2A25MKKG_DeRhGeBK7lMV-S_JwzqIHXVv0s_3rDV6PUJbktCOLXL2kW1NR6e0UHkCGcyvxTYyKB2OV9aloJJ7mUNz; SSOLoginState=1630327279',
# referer 判斷當(dāng)前路徑是不是由上一個(gè)路徑進(jìn)來(lái)的 一般情況下 是做圖片防盜鏈
'referer': 'https://weibo.cn/',
'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
'sec-ch-ua-mobile': '?0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
}
# 請(qǐng)求對(duì)象的定制
request = urllib.request.Request(url=url,headers=headers)
# 模擬瀏覽器向服務(wù)器發(fā)送請(qǐng)求
response = urllib.request.urlopen(request)
# 獲取響應(yīng)的數(shù)據(jù)
content = response.read().decode('utf-8')
# 將數(shù)據(jù)保存到本地
with open('weibo.html','w',encoding='utf-8')as fp:
fp.write(content)
10.Handler處理器
為什么要學(xué)習(xí)handler?
- urllib.request.urlopen(url) 不能定制請(qǐng)求頭
- urllib.request.Request(url,headers,data) 可以定制請(qǐng)求頭
- Handler 定制更高級(jí)的請(qǐng)求頭(隨著業(yè)務(wù)邏輯的復(fù)雜 請(qǐng)求對(duì)象的定制已經(jīng)滿足不了我們的需求(動(dòng)態(tài)cookie和代理 不能使用請(qǐng)求對(duì)象的定制)
# 需求 使用handler來(lái)訪問(wèn)百度 獲取網(wǎng)頁(yè)源碼
import urllib.request
url = 'http://www.baidu.com'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
request = urllib.request.Request(url = url,headers = headers)
# handler build_opener open
# (1)獲取hanlder對(duì)象
handler = urllib.request.HTTPHandler()
# (2)獲取opener對(duì)象
opener = urllib.request.build_opener(handler)
# (3) 調(diào)用open方法
response = opener.open(request)
content = response.read().decode('utf-8')
print(content)
11.代理服務(wù)器
(1)代理的常用功能?
- ①突破自身IP訪問(wèn)限制,訪問(wèn)國(guó)外站點(diǎn)。
- ②訪問(wèn)一些單位或團(tuán)體內(nèi)部資源 擴(kuò)展:某大學(xué)FTP(前提是該代理地址在該資源的允許訪問(wèn)范圍之內(nèi)),使用教育網(wǎng)內(nèi)地址段免費(fèi)代理服務(wù) 器,就可以用于對(duì)教育網(wǎng)開放的各類FTP下載上傳,以及各類資料查詢共享等服務(wù)。
- ③提高訪問(wèn)速度 擴(kuò)展:通常代理服務(wù)器都設(shè)置一個(gè)較大的硬盤緩沖區(qū),當(dāng)有外界的信息通過(guò)時(shí),同時(shí)也將其保存到緩沖 區(qū)中,當(dāng)其他用戶再訪問(wèn)相同的信息時(shí), 則直接由緩沖區(qū)中取出信息,傳給用戶,以提高訪問(wèn)速度。
- ④隱藏真實(shí)IP 擴(kuò)展:上網(wǎng)者也可以通過(guò)這種方法隱藏自己的IP,免受攻擊。
(2)代碼配置代理 創(chuàng)建Reuqest對(duì)象 創(chuàng)建ProxyHandler對(duì)象 用handler對(duì)象創(chuàng)建opener對(duì)象 使用opener.open函數(shù)發(fā)送請(qǐng)求文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-568578.html
import urllib.request
url = 'http://www.baidu.com/s?wd=ip'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
# 請(qǐng)求對(duì)象的定制
request = urllib.request.Request(url = url,headers= headers)
# 模擬瀏覽器訪問(wèn)服務(wù)器
# response = urllib.request.urlopen(request)
proxies = {
'http':'118.24.219.151:16817'
}
# handler build_opener open
handler = urllib.request.ProxyHandler(proxies = proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
# 獲取響應(yīng)的信息
content = response.read().decode('utf-8')
# 保存
with open('daili.html','w',encoding='utf-8')as fp:
fp.write(content)
代理池?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-568578.html
import urllib.request
proxies_pool = [
{'http':'118.24.219.151:16817'},
{'http':'118.24.219.151:16817'},
]
import random
#隨機(jī)選取代理ip
proxies = random.choice(proxies_pool)
url = 'http://www.baidu.com/s?wd=ip'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}
request = urllib.request.Request(url = url,headers=headers)
handler = urllib.request.ProxyHandler(proxies=proxies)
opener = urllib.request.build_opener(handler)
response = opener.open(request)
content = response.read().decode('utf-8')
with open('daili.html','w',encoding='utf-8')as fp:
fp.write(content)
到了這里,關(guān)于Python爬蟲學(xué)習(xí)筆記(三)————urllib的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!