前言??
???????網(wǎng)絡(luò)爬蟲專欄更新中,各位大佬覺得寫得不錯,支持一下,感謝了!??????
Python網(wǎng)絡(luò)爬蟲_熱愛編程的林兮的博客-CSDN博客
?前篇講解了urllib的基本使用、一個類型六個方法與下載相關(guān)內(nèi)容,這篇繼續(xù)講解urlib的其他使用方法。
4、請求對象訂制??
在將這個之前我們先來看看這個:
在上篇中我們?nèi)カ@取百度首頁的源碼是http?開頭的,但是在最新的百度首頁我們可以看到是https開頭
這個時候我們再去進(jìn)行獲取源碼試試:
import urllib.request
url="https://www.baidu.com/"
response = urllib.request.urlopen(url)
content = response.read().decode("utf-8")
print(content)
代碼運行:
就會發(fā)現(xiàn)不一樣,哎,為什么獲取的是這個呢? 這是因為你給數(shù)據(jù)不完整,這是我們現(xiàn)在遇到的第一個反爬,這個時候需要先介紹一下User Agent
UA介紹:User Agent中文名為用戶代理,簡稱 UA,它是一個特殊字符串頭,使得服務(wù)器能夠識別客戶使用的操作系統(tǒng) 及版本、CPU 類型、瀏覽器及版本。瀏覽器內(nèi)核、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等
?UA大全:
User Agent其實無處不在:
?我們可以看到這個里面包含了很多信息,比如Windows版本、瀏覽器版本等等的信息。
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36
我們可以看到這是一個字典類型的數(shù)據(jù),所以我們先要把它放在有一個字典里才能去使用,
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36"}
然后我們添加上headers,運行代碼?
import urllib.request
url="https://www.baidu.com/"
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36"}
response = urllib.request.urlopen(url,headers)
content = response.read().decode("utf-8")
print(content)
發(fā)現(xiàn)還是不可以,報錯了。然后我們?nèi)c擊urlopen,查看源碼
我們看上面源碼, 它說可以放一個Sring字符串或者Request對象,這時候就需要請求對象的定制,回歸了主題。
那我們就把它封裝成一個request對象,然后運行代碼
import urllib.request
url="https://www.baidu.com/"
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36"}
# 因為urlopen萬法中不能存儲字典 所以headers不能傳遞進(jìn)去
# 請求對象的定制
request = urllib.request.Request(url,headers)
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
print(content)
發(fā)現(xiàn)還是報錯了:
這是為什么呢?我們打開Request源碼:
我們可以發(fā)現(xiàn)request中的變量是有順序的,按照順序我們才可以直接傳值(直接寫url和headers),所以我們需要進(jìn)行關(guān)鍵字傳參:
import urllib.request
url="https://www.baidu.com/"
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.36"}
# 因為urlopen萬法中不能存儲字典 所以headers不能傳遞進(jìn)去
# 請求對象的定制
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
print(content)
運行代碼我們就成功爬取出來了:?
這是我們遇到的第一個反爬。?
url的組成??
以這個url為例: https://www.baidu.com/s?wd=周杰倫
協(xié)議 | 主機 | 端口號 | 路徑 | 參數(shù) | 錨點 |
---|---|---|---|---|---|
http或https | www.baidu.com | http 80/https 443 | s | wd=周杰倫 |
編碼的由來??
'''編碼集的演變‐‐‐
由于計算機是美國人發(fā)明的,因此,最早只有127個字符被編碼到計算機里,也就是大小寫英文字母、數(shù)字和一些符號, 這個編碼表被稱為ASCII編碼,比如大寫字母A的編碼是65,小寫字母z的編碼是122。 但是要處理中文顯然一個字節(jié)是不夠的,至少需要兩個字節(jié),而且還不能和ASCII編碼沖突, 所以,中國制定了GB2312編碼,用來把中文編進(jìn)去。 你可以想得到的是,全世界有上百種語言,日本把日文編到Shift_JIS里,韓國把韓文編到Euc‐kr里, 各國有各國的標(biāo)準(zhǔn),就會不可避免地出現(xiàn)沖突,結(jié)果就是,在多語言混合的文本中,顯示出來會有亂碼。 因此,Unicode應(yīng)運而生。Unicode把所有語言都統(tǒng)一到一套編碼里,這樣就不會再有亂碼問題了。 Unicode標(biāo)準(zhǔn)也在不斷發(fā)展,但最常用的是用兩個字節(jié)表示一個字符(如果要用到非常偏僻的字符,就需要4個字節(jié))。 現(xiàn)代操作系統(tǒng)和大多數(shù)編程語言都直接支持Unicode。'''
編解碼??
5、get請求的quote方法(字符串->Unicode編碼)??
?我們可以看到上面的url為
https://www.baidu.com/s?wd=周杰倫
但是我們復(fù)制下來就會變成Unicode編碼:
https://www.baidu.com/s?wd=%E5%91%A8%E6%9D%B0%E4%BC%A6
但是如果是其他漢字情況下,我們不可以一直通過去查詢將漢字轉(zhuǎn)換成Unicode編碼,所以我們需要學(xué)會借助quote方法將中文字符變成對應(yīng)的Unicode編碼
name = urllib.parse.quote('周杰倫')
print(name)
運行結(jié)果:
%E5%91%A8%E6%9D%B0%E4%BC%A6
然后爬取運行這個頁面源碼:?
import urllib.request
url = "https://www.baidu.com/?wd="
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.41"}
# 因為urlopen萬法中不能存儲字典 所以headers不能傳遞進(jìn)去
# 請求對象的定制
name = urllib.parse.quote('周杰倫')
# print(name)
url = url + name
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode("utf-8")
print(content)
運行結(jié)果:?
6、get請求urlencode方法(多個字符串->Unicode編碼)??
https://www.baidu.com/s?wd=周杰倫&sex=男
前面情況是當(dāng)只需要轉(zhuǎn)換少量字符串時 使用quote方法,當(dāng)url中有很多字符串時,我們也是一個一個去轉(zhuǎn)換然后進(jìn)行拼接嗎?
那這樣效率就太慢了。
這時候我們就應(yīng)該使用urlencode方法,下面我來演示一下如何使用:
import urllib.parse
# 要求參數(shù)必須以字典形式存在
data = {
'wd': '周杰倫',
'sex': '男'
}
a = urllib.parse.urlencode(data)
print(a)
運行代碼:
wd=%E5%91%A8%E6%9D%B0%E4%BC%A6&sex=%E7%94%B7
我們可以發(fā)現(xiàn)它自動轉(zhuǎn)換并拼接起來了,這就很方便了,所以當(dāng)有多個字符串(參數(shù))時使用urlencode方法將其直接轉(zhuǎn)換。
那我們來進(jìn)行一個簡單的爬?。?/p>
import urllib.request
import urllib.parse
url = 'https://www.baidu.com/?'
data = {
'wd': '周杰倫',
'sex': '男'
}
data = urllib.parse.urlencode(data)
# 請求資源路徑
url = url + data
headers = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.43"
}
# 請求對象的定制
request = urllib.request.Request(url=url, headers=headers)
# 模擬瀏覽器向服務(wù)器發(fā)送請求
response = urllib.request.urlopen(request)
# 獲取網(wǎng)頁源碼的數(shù)據(jù)
content = response.read().decode("utf-8")
# 打印數(shù)據(jù)
print(content)
運行結(jié)果:?
?7、post請求方式??
打開谷歌瀏覽器,使用英文輸入:spider
打開下面對應(yīng)頁面,找到正確的接口:
?kw對應(yīng)的就是你百度翻譯所輸入的:
?點開預(yù)覽,查看完整數(shù)據(jù):
?那開始進(jìn)行爬取
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/117.0.0.0 Safari/537.36 Edg/117.0.2045.43"
}
# keyword = input('請輸入您要查詢的單詞')
data = {
'kw':'spider'
}
# post請求的參數(shù) 必須要進(jìn)行編碼
data = urllib.parse.urlencode(data).encode('utf‐8')
# post的請求的參數(shù) 是不會拼接在ur1的后面的而是需要放在請求對象定制的參數(shù)中
# post請求的參數(shù)必須要進(jìn)行編碼
request = urllib.request.Request(url=url,headers=headers,data=data)
# 模擬瀏覽器向服務(wù)器發(fā)送請求
response = urllib.request.urlopen(request)
# 獲取響應(yīng)的數(shù)據(jù)
print(response.read().decode('utf‐8'))
?我們運行發(fā)現(xiàn)有數(shù)據(jù)顯示,但是有Unicode編碼亂碼問題
?發(fā)現(xiàn)這是一個json數(shù)據(jù),所以我們應(yīng)該 將其轉(zhuǎn)換成json對象然后輸出
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/117.0.0.0 Safari/537.36 Edg/117.0.2045.43"
}
# keyword = input('請輸入您要查詢的單詞')
data = {
'kw': 'spider'
}
# post請求的參數(shù) 必須要進(jìn)行編碼
data = urllib.parse.urlencode(data).encode('utf‐8')
# post的請求的參數(shù) 是不會拼接在ur1的后面的而是需要放在請求對象定制的參數(shù)中
# post請求的參數(shù)必須要進(jìn)行編碼
request = urllib.request.Request(url=url, headers=headers, data=data)
# 模擬瀏覽器向服務(wù)器發(fā)送請求
response = urllib.request.urlopen(request)
# 獲取響應(yīng)的數(shù)據(jù)
content = response.read().decode('utf‐8')
print(content)
# 查看數(shù)據(jù)類型 字符串類型
print(type(content))
# 字符串-> json對象
import json
obj = json.loads(content)
print(obj)
運行結(jié)果:?文章來源:http://www.zghlxwxcb.cn/news/detail-713271.html
{"errno":0,"data":[{"k":"spider","v":"n. \u8718\u86db; \u661f\u5f62\u8f6e\uff0c\u5341\u5b57\u53c9; \u5e26\u67c4\u4e09\u811a\u5e73\u5e95\u9505; \u4e09\u811a\u67b6"},{"k":"Spider","v":"[\u7535\u5f71]\u8718\u86db"},{"k":"SPIDER","v":"abbr. SEMATECH process induced damage effect revea"},{"k":"spiders","v":"n. \u8718\u86db( spider\u7684\u540d\u8bcd\u590d\u6570 )"},{"k":"spidery","v":"adj. \u50cf\u8718\u86db\u817f\u4e00\u822c\u7ec6\u957f\u7684; \u8c61\u8718\u86db\u7f51\u7684\uff0c\u5341\u5206\u7cbe\u81f4\u7684"}],"logid":1250011545}
<class 'str'>
{'errno': 0, 'data': [{'k': 'spider', 'v': 'n. 蜘蛛; 星形輪,十字叉; 帶柄三腳平底鍋; 三腳架'}, {'k': 'Spider', 'v': '[電影]蜘蛛'}, {'k': 'SPIDER', 'v': 'abbr. SEMATECH process induced damage effect revea'}, {'k': 'spiders', 'v': 'n. 蜘蛛( spider的名詞復(fù)數(shù) )'}, {'k': 'spidery', 'v': 'adj. 像蜘蛛腿一般細(xì)長的; 象蜘蛛網(wǎng)的,十分精致的'}], 'logid': 1250011545}
總結(jié):post和get區(qū)別???
- get請求方式的參數(shù)必須編碼,參數(shù)是拼接到url后面,編碼之后不需要調(diào)用encode方法
- post請求方式的參數(shù)必須編碼,參數(shù)是放在請求對象定制的方法中,編碼之后需要調(diào)用encode方法
文章來源地址http://www.zghlxwxcb.cn/news/detail-713271.html
到了這里,關(guān)于網(wǎng)絡(luò)爬蟲——urllib(2)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!