利用python爬虫(part1)--urllib.request模块
學(xué)習(xí)筆記
文章目錄
- 網(wǎng)絡(luò)爬蟲(chóng)概述
- 定義
- 爬蟲(chóng)分類
- 爬取數(shù)據(jù)步驟
- 爬蟲(chóng)請(qǐng)求模塊
- 常用方法
- urllib.request.urlopen()方法
- 響應(yīng)對(duì)象(response)方法
- 關(guān)于請(qǐng)求頭
- urllib.request.Request()
網(wǎng)絡(luò)爬蟲(chóng)概述
定義
其實(shí)就是用Python程序模仿人點(diǎn)擊瀏覽器并訪問(wèn)網(wǎng)站,而且模仿的越逼真越好。
爬蟲(chóng)分類
①通用網(wǎng)絡(luò)爬蟲(chóng)(搜索引擎使用,需要遵守robots協(xié)議)
robots協(xié)議 :網(wǎng)站通過(guò)robots協(xié)議,告訴搜索引擎哪些頁(yè)面可以抓取,哪些頁(yè)面不能抓取。
比如:www.csdn.net/robots.txt
根據(jù)CSDN的robots協(xié)議,對(duì)于所有的爬蟲(chóng)用戶,Disallow后的內(nèi)容是不可以爬取的。
②聚焦網(wǎng)絡(luò)爬蟲(chóng) :自己寫的爬蟲(chóng)程序(可以不遵守robots協(xié)議)
爬取數(shù)據(jù)步驟
①確定需要爬取的URL地址
②由請(qǐng)求模塊向URL地址發(fā)出請(qǐng)求,并得到網(wǎng)站的響應(yīng)
③從響應(yīng)內(nèi)容中提取所需數(shù)據(jù)
- 提取所需數(shù)據(jù),并保存
- 頁(yè)面中有其他需要繼續(xù)跟進(jìn)的URL地址,回到第2步發(fā)起請(qǐng)求,如此循環(huán)
爬蟲(chóng)請(qǐng)求模塊
- 模塊
常用方法
urllib.request.urlopen()方法
- 作用
向網(wǎng)站發(fā)起請(qǐng)求,并獲取響應(yīng)對(duì)象
- 語(yǔ)法
響應(yīng)對(duì)象(response)方法
#獲取響應(yīng)對(duì)象的內(nèi)容 bytes = response.read() string = response.read().decode('utf-8') # 返回實(shí)際數(shù)據(jù)的URL地址 url = response.geturl() # HTTP響應(yīng)碼(比如:200/404等) code = response.getcode() #編碼 string.encode() # string -> bytes #解碼 bytes.decode() # bytes -> string下面,我們先舉一個(gè)例子,來(lái)了解一下網(wǎng)爬的流程。
- 舉個(gè)例子
首先,我們向微博(https://www.weibo.com/)發(fā)起請(qǐng)求,并得到微博的響應(yīng)對(duì)象:
#導(dǎo)入請(qǐng)求模塊 import urllib.request#向微博發(fā)起請(qǐng)求(注意:地址要寫全),得到響應(yīng)對(duì)象 response = urllib.request.urlopen('https://www.weibo.com/') print(response)結(jié)果:
<http.client.HTTPResponse object at 0x000000EA0B11EBA8>備注:在python中發(fā)起請(qǐng)求時(shí),網(wǎng)站地址要寫全。
平時(shí)我們寫的網(wǎng)址,就是URL地址
URL協(xié)議規(guī)定了URL地址的格式。
URL地址舉例:http://news.sina.com.cn/c/zg/2015-10-27/doc-ifxizwsm2427861.shtml
URL協(xié)議規(guī)定格式:scheme://host.domain:port/path/filename scheme - 定義因特網(wǎng)服務(wù)的類型。最常見(jiàn)的類型是 http, https,ftp host - 定義域主機(jī)(http 的默認(rèn)主機(jī)是 www) domain - 定義因特網(wǎng)域名,比如news.sina.com.cn port - 定義主機(jī)上的端口號(hào)(http 的默認(rèn)端口號(hào)是 80) path - 定義服務(wù)器上的路徑(如果省略,則文檔必須位于網(wǎng)站的根目錄中)。 filename - 定義文檔/資源的名稱獲取響應(yīng)對(duì)象的內(nèi)容(網(wǎng)頁(yè)源代碼):
wangye = response.read() print(wangye)部分結(jié)果:
我們得到的是byte數(shù)據(jù)類型的網(wǎng)頁(yè)源代碼。
我們?cè)僖評(píng)tf-8編碼形式對(duì)byte數(shù)據(jù)類型的網(wǎng)頁(yè)源代碼進(jìn)行解碼,得到字符串類型的網(wǎng)頁(yè)源代碼:
wangye = response.read().decode('utf-8') print(wangye)結(jié)果:
UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xca in position 339: invalid continuation byte
報(bào)錯(cuò)!發(fā)生了UnicodeDecodeError錯(cuò)誤。
原因可能是新浪的網(wǎng)頁(yè)源代碼中使用了中文字符。故我們改用gbk編碼格式,進(jìn)行解碼:
wangye = response.read().decode('gbk') print(wangye)部分結(jié)果:
返回獲取數(shù)據(jù)的URL地址和HTTP響應(yīng)碼:
url = response.geturl() code = response.getcode() print(url) print(code)結(jié)果:
https://passport.weibo.com/visitor/visitor?entry=miniblog&a=enter&url=https%3A%2F%2Fweibo.com%2F&domain=.weibo.com&ua=php-sso_sdk_client-0.6.28&_rand=1585717972.5771 響應(yīng)碼: 200關(guān)于請(qǐng)求頭
在我們向一個(gè)網(wǎng)站發(fā)起請(qǐng)求時(shí),一定會(huì)發(fā)送請(qǐng)求頭。當(dāng)網(wǎng)站收到我們的請(qǐng)求時(shí),首先會(huì)檢查我們請(qǐng)求頭中User-Agent。 如果我們用瀏覽器發(fā)起請(qǐng)求,則此時(shí),User-Agent中會(huì)有操作系統(tǒng)、瀏覽器版本、內(nèi)核等信息;但是如果我們用程序發(fā)起請(qǐng)求,并且沒(méi)有設(shè)置請(qǐng)求頭,則此時(shí)User-Agent會(huì)顯得”不正常”,故網(wǎng)站會(huì)很容易的發(fā)現(xiàn)我們是通過(guò)爬蟲(chóng)訪問(wèn)的,而不是正常的瀏覽器訪問(wèn)。
我們利用一個(gè)測(cè)試網(wǎng)站(http://httpbin.org/get, 當(dāng)我們向這個(gè)網(wǎng)站發(fā)起請(qǐng)求時(shí),網(wǎng)站會(huì)返回我們的請(qǐng)求頭)做一個(gè)小測(cè)試:
我們先用Chrome瀏覽器,訪問(wèn)這個(gè)測(cè)試網(wǎng)站,這個(gè)網(wǎng)站會(huì)返回給我們?nèi)缦抡?qǐng)求頭:
{"args": {}, "headers": {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Host": "httpbin.org", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-5e8426bf-69a4172ea646d941270576d5"}, "origin": "114.105.135.48", "url": "http://httpbin.org/get" }可以看到,我們通過(guò)Chrome瀏覽器進(jìn)行請(qǐng)求的User-Agent為Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36。
我們?cè)儆贸绦蛟L問(wèn),代碼如下:
#導(dǎo)入請(qǐng)求模塊 import urllib.request#向微博發(fā)起請(qǐng)求(注意:地址要寫全),得到響應(yīng)對(duì)象 response = urllib.request.urlopen('http://httpbin.org/get') #print(response)wangye = response.read().decode('utf-8') print(wangye)結(jié)果:
{"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.6", "X-Amzn-Trace-Id": "Root=1-5e8426f1-ca27dd62e83b367c4715d4a0"}, "origin": "114.105.135.48", "url": "http://httpbin.org/get" }可以看到,我們通過(guò)程序訪問(wèn)的User-Agent為:“Python-urllib/3.6”,這顯然不是正常瀏覽器的User-Agent,一般的網(wǎng)頁(yè)如果看到這樣的User-Agent,會(huì)直接把我們的請(qǐng)求槍斃。
所以這時(shí),我們要自己包裝一個(gè)請(qǐng)求頭,偽裝成正常的瀏覽器,欺騙網(wǎng)頁(yè)進(jìn)行訪問(wèn)。可惜的是,我們的urlopen()方法并不支持包裝請(qǐng)求頭,我們需要學(xué)習(xí)新的內(nèi)容對(duì)請(qǐng)求頭進(jìn)行包裝。
urllib.request.Request()
- 作用
創(chuàng)建請(qǐng)求對(duì)象(包裝請(qǐng)求,重構(gòu)User-Agent,使程序更像正常人類請(qǐng)求,避免網(wǎng)站反爬)
注意這里只是創(chuàng)建請(qǐng)求對(duì)象,并沒(méi)有發(fā)起請(qǐng)求。
- 語(yǔ)法
- 使用流程
- 舉個(gè)例子
向測(cè)試網(wǎng)站http://httpbin.org/get發(fā)起請(qǐng)求,構(gòu)造請(qǐng)求頭,并檢查響應(yīng)對(duì)象內(nèi)容:
import urllib.requesturl = 'http://httpbin.org/get' headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0)'}#User-Agent可以自己在網(wǎng)上隨便找 req = urllib.request.Request(url = url, headers = headers)response = urllib.request.urlopen(req) print(response.read().decode('utf-8'))網(wǎng)站返回的請(qǐng)求頭:
{"args": {}, "headers": {"Accept-Encoding": "identity", "Host": "httpbin.org", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0)", "X-Amzn-Trace-Id": "Root=1-5e86b85a-3d13d9b784ee0ef05416b377"}, "origin": "183.164.105.16", "url": "http://httpbin.org/get" }可以看到,我們的User-Agent已經(jīng)改變了。初步偽裝成功!
總結(jié)
以上是生活随笔為你收集整理的利用python爬虫(part1)--urllib.request模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Flash相册制作大师怎么用
- 下一篇: 利用python爬虫(part2)--u