Python中的urllib庫高級用法教程
綜述
本系列文檔用于對Python爬蟲技術(shù)進(jìn)行簡單的教程講解,鞏固自己技術(shù)知識的同時,萬一一不小心又正好對你有用那就更好了。
Python 版本是3.7.4
上篇文章介紹了urllib的基礎(chǔ)使用方法本篇文章就來介紹一下urllib稍微高級一點的用法。
網(wǎng)上有很多的網(wǎng)站想要請求需要設(shè)置一些請求頭,如果要在請求的時候增加一些請求頭,那么就必須使用request.Request類來實現(xiàn)了,比如要增加一個 User-Agent
,增加一個 Referer
頭信息等。
通常防止爬蟲被反主要有以下幾個策略:
- 動態(tài)設(shè)置請求頭headers(User-Agent)(隨機切換User-Agent,模擬不同用戶的瀏覽器信息)
- 使用IP地址池:VPN和代理IP,現(xiàn)在大部分網(wǎng)站都是根據(jù)IP來ban的
- Cookies
- 設(shè)置延遲下載(防止訪問過于頻繁,設(shè)置為2秒或更高)要明白爬蟲重要的是拿到數(shù)據(jù)(這個用到time庫的time.sleep()方法,在這里不在說明)
設(shè)置請求頭(urllib.request.Request)
urllib.request.Request是urllib的一個抽象類,用于構(gòu)造一個http請求對象實例。 request類Request方法常用的內(nèi)置方法:
- Request.add_data(data)設(shè)置data參數(shù),如果一開始創(chuàng)建的時候沒有給data參數(shù),那么可以使用該方法追加data參數(shù);
- Request.get_method() 返回HTTP請求方法,一般返回GET或是POST;
- Request.has_data() 查看是否設(shè)置了data參數(shù);
- Request.get_data() 獲取data參數(shù)的數(shù)據(jù);
- Request.add_header(key, val) 添加頭部信息,key為頭域名,val為域值;
- Request.get_full_url() 獲取請求的完整url;
- Request.get_host() 返回請求url的host(主域名);
- Request.set_proxy(host, type) 設(shè)置代理,第一個參數(shù)是代理ip和端口,第二個參數(shù)是代理類型(http/https)。
代碼示例
# 導(dǎo)入urllib庫 import urllib.parse import urllib.request # 聲明定義請求頭 headers = { # 在這個頭字典里面可以將你所有需要傳遞的頭添加進(jìn)來 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } # 向指定的url發(fā)送請求,并返回 post_url = 'https://fanyi.baidu.com/sug' # 傳入?yún)?shù) form_data = { 'kw': 'honey' } # 格式化參數(shù) form_data = urllib.parse.urlencode(form_data).encode() # 創(chuàng)建Request類 req = urllib.request.Request(url=post_url, headers=headers, data=form_data) # 進(jìn)行請求,打印結(jié)果 ret = urllib.request.urlopen(req) print(ret.read())
爬蟲示例
爬取拉勾網(wǎng)Python職位招聘信息(由于拉勾網(wǎng)進(jìn)行了防爬,訪問其接口需要傳遞Cookie,本人直接在瀏覽器復(fù)制出來寫入到請求頭中的)。
# 引入urllib庫 import urllib.parse import urllib.request # 聲明定義請求頭 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36', 'Referer': 'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=', 'Host': 'www.lagou.com', 'Origin': 'https://www.lagou.com', 'X-Requested-With': 'XMLHttpRequest', 'Cookie': '_ga=GA1.2.1158944803.1554684888; user_trace_token=20190408085447-e8216b55-5998-11e9-8cbc-5254005c3644; LGUID=20190408085447-e8216df3-5998-11e9-8cbc-5254005c3644; JSESSIONID=ABAAABAAAFCAAEG89414A0A463BB593A6FCB8B25161B297; WEBTJ-ID=20190803154150-16c566d76a7a71-0d0261dbc1a413-a7f1a3e-2073600-16c566d76a8664; _gid=GA1.2.646413362.1564818110; Hm_lvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1564818110; LGSID=20190803154149-2746a012-b5c2-11e9-8700-525400f775ce; PRE_UTM=; PRE_HOST=www.baidu.com; PRE_SITE=https%3A%2F%2Fwww.baidu.com%2F; PRE_LAND=https%3A%2F%2Fwww.lagou.com%2F; index_location_city=%E5%85%A8%E5%9B%BD; X_HTTP_TOKEN=7b450c20fc1c8ebb1028184651d95c44e86182119a; Hm_lpvt_4233e74dff0ae5bd0a3d81c6ccf756e6=1564818202; _gat=1; LGRID=20190803154322-5e321a85-b5c2-11e9-8700-525400f775ce; TG-TRACK-CODE=index_search; SEARCH_ID=f2eeeba9273a435281d59597e5b8b7ba', } # 拉鉤接口地址 url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false' # 接口參數(shù) data = { 'first': 'true', 'pn': '1', 'kd': 'python' } from_data = urllib.parse.urlencode(data).encode() # 聲明定義Request類 req = urllib.request.Request(url=url, headers=headers, data=from_data) # 請求接口,打印結(jié)果 res = urllib.request.urlopen(req) print(res.read().decode())
使用代理(urllib.request.ProxyHandle)
很多網(wǎng)站會員檢測某一時間內(nèi)某個IP的訪問次數(shù)(通過流量統(tǒng)計,系統(tǒng)日志等),如果訪問次數(shù)多的不像正常人,它就會禁止這個IP訪問。所以我們可以設(shè)置一些代理服務(wù)器,每隔一段時間換一個代理,就算IP被禁止,依然可以換個IP繼續(xù)爬取。
基本原理
代理實際上指的就是代理服務(wù)器,它的功能是代理網(wǎng)絡(luò)用戶去取得網(wǎng)絡(luò)信息。形象地說,它是網(wǎng)絡(luò)信息的中轉(zhuǎn)站。在我們正常請求一個網(wǎng)站時,其實是發(fā)送了請求給Web服務(wù)器,Web服務(wù)器把響應(yīng)傳回給我們。如果設(shè)置了代理服務(wù)器,實際上就是在本機和服務(wù)器之間搭建了一個橋,此時本機不是直接向Web服務(wù)器發(fā)起請求,而是向代理服務(wù)器發(fā)出請求,請求會發(fā)送給代理服務(wù)器,然后由代理服務(wù)器再發(fā)送給Web服務(wù)器,接著由代理服務(wù)器再把Web服務(wù)器返回的響應(yīng)轉(zhuǎn)發(fā)給本機。這樣我們同樣可以正常訪問網(wǎng)頁,但這個過程中Web服務(wù)器識別出的真實IP就不再是我們本機的IP了,就成功實現(xiàn)了IP偽裝,這就是代理的基本原理。
作用
- 突破自身IP訪問限制,訪問一些平時不能訪問的站點;
- 提高訪問速度;
- 隱藏真實IP。
常用的代理
- 西刺代理 : https://www.xicidaili.com/
- 快代理 : https://www.kuaidaili.com/
- 云代理 : http://www.ip3366.net/
用法示例
# 引入所需要的庫 import random import urllib.request # 聲明定義代理服務(wù)器列表 proxy_list = [ {"http": "220.184.144.80:8060"}, {"http": "180.175.170.210:8060"}, {"http": "116.226.28.17:8060"}, {"http": "123.123.137.72:8060"}, {"http": "116.226.31.161:8060"} ] # 隨機選擇一個代理 proxy = random.choice(proxy_list) # 使用選擇的代理構(gòu)建代理處理器對象 http_proxy_handler = urllib.request.ProxyHandler(proxy) # 通過 urllib.request.build_opener(),創(chuàng)建自定義opener對象 opener = urllib.request.build_opener(http_proxy_handler) # 創(chuàng)建Request對象 url = 'http://www.baidu.com/s?ie=UTF-8&wd=ip' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } req = urllib.request.Request(url=url, headers=headers) # 使用opener.open()方法發(fā)送請求才使用自定義的代理,而urlopen()則不使用自定義代理 # 這么寫,就是將opener應(yīng)用到全局,之后所有的,不管是opener.open()還是urlopen()發(fā)送請求,都將使用自定義代理 res = opener.open(req) print(res.read().decode())
Cookie(urllib.request.HTTPCookieProcessor)
cookie是什么
在網(wǎng)站中,http請求時無狀態(tài)的,也就是說即使第一次和服務(wù)器鏈接后并且登陸成功后,第二次請求服務(wù)器依然不能知道當(dāng)前請求是那個用戶,cookie的出現(xiàn)就是為了解決這個問題,第一次登陸后服務(wù)器返回一些數(shù)據(jù)(cookie)給瀏覽器,然后瀏覽器保存在本地,當(dāng)該用戶第二次請求的時候,就會自動把上次請求的cookie數(shù)據(jù)自動的攜帶給服務(wù)器,服務(wù)器通過瀏覽器攜帶的cookie數(shù)據(jù)就能判斷當(dāng)前的用戶是那個了。cookie存儲的數(shù)據(jù)有限,不同的瀏覽器又不同的存儲大小,但一般不超過4kb,因此使用cookie只能存儲一些小量的數(shù)據(jù)。(解釋比較簡單,詳細(xì)的cookie說明可以看百科介紹)
cookie格式
Set-Cookie: NAME=VALUE; Expires=DATE; Domain=DOMAIN_NAME; Path=PATH; SECURE
- NAME=VALUE:這是每一個Cookie均必須有的部分。NAME是該Cookie的名稱,VALUE是該Cookie的值。在字符串“NAME=VALUE”中,不含分號、逗號和空格等字符;
- Expires=DATE:Expires變量是一個只寫變量,它確定了Cookie有效終止日期。該變量可省,如果缺省時,則Cookie的屬性值不會保存在用戶的硬盤中,而僅僅保存在內(nèi)存當(dāng)中,Cookie文件將隨著瀏覽器的關(guān)閉而自動消失;
- Domain=DOMAIN-NAME:Domain該變量是一個只寫變量,它確定了哪些Internet域中的Web服務(wù)器可讀取瀏覽器所存取的Cookie,即只有來自這個域的頁面才可以使用Cookie中的信息。這項設(shè)置是可選的,如果缺省時,設(shè)置Cookie的屬性值為該Web服務(wù)器的域名;
- Path=PATH:Path屬性定義了Web服務(wù)器上哪些路徑下的頁面可獲取服務(wù)器設(shè)置的Cookie;
- SECURE:在Cookie中標(biāo)記該變量,表明只有當(dāng)瀏覽器的通信協(xié)議為加密認(rèn)證協(xié)議時,瀏覽器才向服務(wù)器提交相應(yīng)的Cookie。當(dāng)前這種協(xié)議只有一種,即為HTTPS。
http.cookiejar
cookielib一般用于客戶端處理HTTP cookie信息,通過它可以從服務(wù)器端獲取cookie信息,反過來又可以通過它將獲取到的cookie發(fā)送給服務(wù)器。cookielib提供了不同的類來自動處理HTTP的cookie信息,使用比較多的類包括了CookieJar、MozillaCookieJar以及Cookie。
代碼使用示例(使用http.cookiejar和urllib.request.HTTPCookieProcessor登陸人人網(wǎng)):
# 引入所需要的庫 import http.cookiejar import urllib.parse import urllib.request # 真實的模擬瀏覽器,當(dāng)發(fā)送完post請求的時候,將cookie保存到代碼中 # 創(chuàng)建一個cookiejar對象 cj = http.cookiejar.CookieJar() # 通過cookiejar創(chuàng)建一個handler handler = urllib.request.HTTPCookieProcessor(cj) # 根據(jù)handler創(chuàng)建一個opener opener = urllib.request.build_opener(handler) # 人人網(wǎng)登陸地址 post_uel = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=2019621044248' form_data = { 'email': '188****7357', # 這是人人網(wǎng)賬號 'icode': '', 'origURL': 'http://www.renren.com/home', 'domain': 'renren.com', 'key_id': '1', 'captcha_type': 'web_login', 'password': '01cb55635986f56265d3b55aaddaa79337d094cb56d6cf7724343a93ad586fe7', 'rkey': 'd5ff51375d8eb17a011cad5622d835fd', 'f': 'http%3A%2F%2Fwww.renren.com%2F971686685%2Fprofile' } # 聲明定義header headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36' } # 創(chuàng)建Request對象,格式化參數(shù) req = urllib.request.Request(url=post_uel, headers=headers) form_data = urllib.parse.urlencode(form_data).encode() # 構(gòu)造訪問 res = opener.open(req, data=form_data) print(res.read().decode()) print('*' * 50) # 人人網(wǎng)個人中心地址 get_url = 'http://www.renren.com/971686685/profile' # 創(chuàng)建Request對象 req1 = urllib.request.Request(url=get_url, headers=headers) # 構(gòu)造訪問(自帶cookie),打印結(jié)果 res1 = opener.open(req1) print(res1.read().decode())
cookie信息的保存
# 引入所需要的庫 import urllib.request from http.cookiejar import MozillaCookieJar # 聲明cookiejar cj = MozillaCookieJar('cookie.txt') # 創(chuàng)建handler\opener handler = urllib.request.HTTPCookieProcessor(cj) opener = urllib.request.build_opener(handler) # 聲明定義url,進(jìn)行訪問 url = 'http://httpbin.org/cookies/set?wei=weizhihua' res = opener.open(url) # 保存cookie, ignore_discard 設(shè)置為True,將過期的cookie也進(jìn)行保存 # 如果在聲明cookiejar時沒有寫入文件保存地址,則在save()函數(shù)中需寫入文件地址參數(shù) cj.save(ignore_discard=True)
cookie信息的加載
import urllib.request from http.cookiejar import MozillaCookieJar # 聲明cookiejar cj = MozillaCookieJar('cookie.txt') # ignore_discard 設(shè)置為True,將過期的cookie也加載出來 cj.load(ignore_discard=True) # 打印內(nèi)容 for cookie in cj: print(cookie)
到此這篇關(guān)于Python中的urllib庫高級用法教程的文章就介紹到這了,更多相關(guān)urllib庫高級用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 利用pandas將arff文件轉(zhuǎn)csv文件的方法
今天小編就為大家分享一篇python 利用pandas將arff文件轉(zhuǎn)csv文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-02-02詳解pandas中MultiIndex和對象實際索引不一致問題
這篇文章主要介紹了詳解pandas中MultiIndex和對象實際索引不一致問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Python docx庫刪除復(fù)制paragraph及行高設(shè)置圖片插入示例
這篇文章主要為大家介紹了Python docx庫刪除復(fù)制paragraph及行高設(shè)置圖片插入操作實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07django進(jìn)階之cookie和session的使用示例
這篇文章主要介紹了django進(jìn)階之cookie和session的使用示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Python使用itchat模塊實現(xiàn)群聊轉(zhuǎn)發(fā),自動回復(fù)功能示例
這篇文章主要介紹了Python使用itchat模塊實現(xiàn)群聊轉(zhuǎn)發(fā),自動回復(fù)功能,結(jié)合實例形式分析了Python基于itchat模塊針對微信信息的發(fā)送、回復(fù)等相關(guān)操作技巧,需要的朋友可以參考下2019-08-08