您好,登錄后才能下訂單哦!
一爬蟲的定義:
所謂爬蟲就是指:可以獲取網(wǎng)頁信息的程序
又分為通用爬蟲和聚焦爬蟲
1)通用爬蟲:從互聯(lián)網(wǎng)中搜集網(wǎng)頁,采集信息,這些網(wǎng)頁信息用于為搜索引擎建立索引從而提供支持,它決定著整個引擎系統(tǒng)的內(nèi)容是否豐富,信息是否即時,因此其性能的優(yōu)劣直接影響著搜索引擎的效果。
抓取流程:
除了HTML文件外,搜索引擎通常還能抓取和索引以文字為基礎(chǔ)的多種文件類型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我們在搜索結(jié)果中也經(jīng)常會看到這些文件類型。
搜索引擎還不能處理圖片、視頻、Flash 這類非文字內(nèi)容,也不能執(zhí)行腳本和程序。
但是,這些通用性搜索引擎也存在著一定的局限性:
(1)通用搜索引擎所返回的結(jié)果都是網(wǎng)頁,而大多情況下,網(wǎng)頁里90%的內(nèi)容對用戶來說都是無用的。
(2)不同領(lǐng)域、不同背景的用戶往往具有不同的檢索目的和需求,搜索引擎無法提供針對具體某個用戶的搜索結(jié)果。
(3)萬維網(wǎng)數(shù)據(jù)形式的豐富和網(wǎng)絡(luò)技術(shù)的不斷發(fā)展,圖片、數(shù)據(jù)庫、音頻、視頻多媒體等不同數(shù)據(jù)大量出現(xiàn),通用搜索引擎對這些文件無能為力,不能很好地發(fā)現(xiàn)和獲取。
(4)通用搜索引擎大多提供基于關(guān)鍵字的檢索,難以支持根據(jù)語義信息提出的查詢,無法準確理解用戶的具體需求。
2)聚焦爬蟲
聚焦爬蟲,是"面向特定主題需求"的一種網(wǎng)絡(luò)爬蟲程序,它與通用搜索引擎爬蟲的區(qū)別在于: 聚焦爬蟲在實施網(wǎng)頁抓取時會對內(nèi)容進行處理篩選,盡量保證只抓取與需求相關(guān)的網(wǎng)頁信息。
二瀏覽器發(fā)送HTTP請求的過程中涉及的部分內(nèi)容:
1)當用戶在瀏覽器的地址欄中輸入一個URL并按回車鍵之后,瀏覽器會向HTTP服務(wù)器發(fā)送HTTP請求。HTTP請求主要分為“Get”和“Post”兩種方法。
2)當我們在瀏覽器輸入URL http://www.baidu.com 的時候,瀏覽器發(fā)送一個Request請求去獲取 http://www.baidu.com 的html文件,服務(wù)器把Response文件對象發(fā)送回給瀏覽器。
3)瀏覽器分析Response中的 HTML,發(fā)現(xiàn)其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。 瀏覽器會自動再次發(fā)送Request去獲取圖片,CSS文件,或者JS文件。
4)當所有的文件都下載成功后,網(wǎng)頁會根據(jù)HTML語法結(jié)構(gòu),完整的顯示出來了。
URL(Uniform / Universal Resource Locator的縮寫):統(tǒng)一資源定位符,是用于完整地描述Internet上網(wǎng)頁和其他資源的地址的一種標識方法。
基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]
scheme:協(xié)議(例如:http, https, ftp)
host:服務(wù)器的IP地址或者域名
port#:服務(wù)器的端口(如果是走協(xié)議默認端口,缺省端口80)
path:訪問資源的路徑
query-string:參數(shù),發(fā)送給http服務(wù)器的數(shù)據(jù)
anchor:錨(跳轉(zhuǎn)到網(wǎng)頁的指定錨點位置)
例如:
ftp://192.168.0.116:8080/index
http://www.baidu.com
http://item.jd.com/11936238.html#product-detail
5)HTTP請求主要分為Get和Post兩種方法:
GET是從服務(wù)器上獲取數(shù)據(jù),POST是向服務(wù)器傳送數(shù)據(jù)
GET請求參數(shù)顯示,都顯示在瀏覽器網(wǎng)址上,HTTP服務(wù)器根據(jù)該請求所包含URL中的參數(shù)來產(chǎn)生響應內(nèi)容,即“Get”請求的參數(shù)是URL的一部分。 例如: http://www.baidu.com/s?wd=Chinese
POST請求參數(shù)在請求體當中,消息長度沒有限制而且以隱式的方式進行發(fā)送,通常用來向HTTP服務(wù)器提交量比較大的數(shù)據(jù)(比如請求中包含許多參數(shù)或者文件上傳操作等),請求的參數(shù)包含在“Content-Type”消息頭里,指明該消息體的媒體類型和編碼,
注意:避免使用Get方式提交表單,因為有可能會導致安全問題。 比如說在登陸表單中用Get方式,用戶輸入的用戶名和密碼將在地址欄中暴露無遺。
6)常用的請求報頭:
Host (主機和端口號)
Connection (鏈接類型)
Upgrade-Insecure-Requests (升級為HTTPS請求)
User-Agent (瀏覽器名稱)
Accept (傳輸文件類型)
Referer (頁面跳轉(zhuǎn)處)
Accept-Encoding(文件編解碼格式)
Accept-Language(語言種類)
Accept-Charset(字符編碼)
Cookie (Cookie)
Content-Type (POST數(shù)據(jù)類型)
7)常用的響應報頭(了解)
Cache-Control:must-revalidate, no-cache, private。
這個值告訴客戶端,服務(wù)端不希望客戶端緩存資源,在下次請求資源時,必須要從新請求服務(wù)器,不能從緩存副本中獲取資源。
Connection:keep-alive
這個字段作為回應客戶端的Connection:keep-alive,告訴客戶端服務(wù)器的tcp連接也是一個長連接,客戶端可以繼續(xù)使用這個tcp連接發(fā)送http請求。
Content-Encoding:gzip
告訴客戶端,服務(wù)端發(fā)送的資源是采用gzip編碼的,客戶端看到這個信息后,應該采用gzip對資源進行解碼。
Content-Type:text/html;charset=UTF-8
告訴客戶端,資源文件的類型,還有字符編碼,客戶端通過utf-8對資源進行解碼,然后對資源進行html解析。通常我們會看到有些網(wǎng)站是亂碼的,往往就是服務(wù)器端沒有返回正確的編碼。
Date:Sun, 21 Sep 2016 06:18:21 GMT
這個是服務(wù)端發(fā)送資源時的服務(wù)器時間,GMT是格林尼治所在地的標準時間。http協(xié)議中發(fā)送的時間都是GMT的,這主要是解決在互聯(lián)網(wǎng)上,不同時區(qū)在相互請求資源的時候,時間混亂問題。
Expires:Sun, 1 Jan 2000 01:00:00 GMT
這個響應頭也是跟緩存有關(guān)的,告訴客戶端在這個時間前,可以直接訪問緩存副本,很顯然這個值會存在問題,因為客戶端和服務(wù)器的時間不一定會都是相同的,如果時間不同就會導致問題。所以這個響應頭是沒有Cache-Control:max-age=*這個響應頭準確的,因為max-age=date中的date是個相對時間,不僅更好理解,也更準確。
Pragma:no-cache
這個含義與Cache-Control等同。
Server:Tengine/1.4.6
這個是服務(wù)器和相對應的版本,只是告訴客戶端服務(wù)器的信息。
Transfer-Encoding:chunked
這個響應頭告訴客戶端,服務(wù)器發(fā)送的資源的方式是分塊發(fā)送的。一般分塊發(fā)送的資源都是服務(wù)器動態(tài)生成的,在發(fā)送時還不知道發(fā)送資源的大小,所以采用分塊發(fā)送,每一塊都是獨立的,獨立的塊都能標示自己的長度,最后一塊是0長度的,當客戶端讀到這個0長度的塊時,就可以確定資源已經(jīng)傳輸完了。
Vary: Accept-Encoding
告訴緩存服務(wù)器,緩存壓縮文件和非壓縮文件兩個版本,現(xiàn)在這個字段用處并不大,因為現(xiàn)在的瀏覽器都是支持壓縮的。
8)響應狀態(tài)碼
響應狀態(tài)代碼有三位數(shù)字組成,第一個數(shù)字定義了響應的類別,且有五種可能取值。
常見狀態(tài)碼:
100~199:表示服務(wù)器成功接收部分請求,要求客戶端繼續(xù)提交其余請求才能完成整個處理過程。
200~299:表示服務(wù)器成功接收請求并已完成整個處理過程。常用200(OK 請求成功)。
300~399:為完成請求,客戶需進一步細化請求。例如:請求的資源已經(jīng)移動一個新地址、常用302(所請求的頁面已經(jīng)臨時轉(zhuǎn)移至新的url)、307和304(使用緩存資源)。
400~499:客戶端的請求有錯誤,常用404(服務(wù)器無法找到被請求的頁面)、403(服務(wù)器拒絕訪問,權(quán)限不夠)。
500~599:服務(wù)器端出現(xiàn)錯誤,常用500(請求未完成。服務(wù)器遇到不可預知的情況)。
9)Cookie 和 Session:
服務(wù)器和客戶端的交互僅限于請求/響應過程,結(jié)束之后便斷開,在下一次請求時,服務(wù)器會認為新的客戶端。
為了維護他們之間的鏈接,讓服務(wù)器知道這是前一個用戶發(fā)送的請求,必須在一個地方保存客戶端的信息。
Cookie:通過在 客戶端 記錄的信息確定用戶的身份。
Session:通過在 服務(wù)器端 記錄的信息確定用戶的身份。
三 爬蟲程序中常用的幾個庫
1 urllib2庫
1)urllib2 是 Python2.7 自帶的模塊(不需要下載,導入即可使用)
urllib2 官方文檔:https://docs.python.org/2/library/urllib2.html
urllib2 源碼:https://hg.python.org/cpython/file/2.7/Lib/urllib2.py
urllib2 在 python3.x 中被改為urllib.request
2) 此庫中常用的request()和urlopen()方法
import urllib2
#url 作為Request()方法的參數(shù),構(gòu)造并返回一個Request對象
request = urllib2.Request("http://www.baidu.com")
#Request對象作為urlopen()方法的參數(shù),發(fā)送給服務(wù)器并接收響應
response = urllib2.urlopen(request)
html = response.read()
print html
3)新建Request實例,除了必須要有 url 參數(shù)之外,還可以設(shè)置另外兩個參數(shù):
data(默認空):是伴隨 url 提交的數(shù)據(jù)(比如要post的數(shù)據(jù)),同時 HTTP 請求將從 "GET"方式 改為 "POST"方式。
headers(默認空):是一個字典,包含了需要發(fā)送的HTTP報頭的鍵值對。
這兩個參數(shù)下面會說到。
User-Agent
但是如果我們用一個合法的身份去請求別人網(wǎng)站,顯然人家就是歡迎的,所以我們就應該給我們的這個代碼加上一個身份,就是所謂的User-Agent頭。
瀏覽器 就是互聯(lián)網(wǎng)世界上公認被允許的身份,如果我們希望我們的爬蟲程序更像一個真實用戶,那我們第一步,就是需要偽裝成一個被公認的瀏覽器。用不同的瀏覽器在發(fā)送請求的時候,會有不同的User-Agent頭。 urllib2默認的User-Agent頭為:Python-urllib/x.y(x和y是Python主版本和次版本號,例如 Python-urllib/2.7)
示例:
隨機添加/修改User-Agent
#urllib2_add_headers.py
import urllib2
import random
url = "http://www.itcast.cn"
ua_list = [
"Mozilla/5.0 (Windows NT 6.1; ) Apple.... ",
"Mozilla/5.0 (X11; CrOS i686 2268.111.0)... ",
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X.... ",
"Mozilla/5.0 (Macintosh; Intel Mac OS... "
]
user_agent = random.choice(ua_list)
request = urllib2.Request(url)
#也可以通過調(diào)用Request.add_header() 添加/修改一個特定的header
request.add_header("User-Agent", user_agent)
#第一個字母大寫,后面的全部小寫
request.get_header("User-agent")
response = urllib2.urlopen(req)
html = response.read()
print html
4)urllib2默認只支持HTTP/HTTPS的GET和POST方法
urllib.urlencode():
urllib 和 urllib2 都是接受URL請求的相關(guān)模塊,但是提供了不同的功能。兩個最顯著的不同如下:
urllib 僅可以接受URL,不能創(chuàng)建 設(shè)置了headers 的Request 類實例;
但是 urllib 提供 urlencode 方法用來GET查詢字符串的產(chǎn)生,而 urllib2 則沒有。(這是 urllib 和 urllib2 經(jīng)常一起使用的主要原因)
編碼工作使用urllib的urlencode()函數(shù),幫我們將key:value這樣的鍵值對轉(zhuǎn)換成"key=value"這樣的字符串,解碼工作可以使用urllib的unquote()函數(shù)。(注意,不是urllib2.urlencode() )
一般HTTP請求提交數(shù)據(jù),需要編碼成 URL編碼格式,然后做為url的一部分,或者作為參數(shù)傳到Request對象中。
Get方式:
GET請求一般用于我們向服務(wù)器獲取數(shù)據(jù),比如說,我們用百度搜索傳智播客:https://www.baidu.com/s?wd=傳智播客
5)Handler處理器 和 自定義Opener
opener是 urllib2.OpenerDirector 的實例,我們之前一直都在使用的urlopen,它是一個特殊的opener(也就是模塊幫我們構(gòu)建好的)。
但是基本的urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高級功能。所以要支持這些功能:
用相關(guān)的 Handler處理器 來創(chuàng)建特定功能的處理器對象;
然后通過 urllib2.build_opener()方法使用這些處理器對象,創(chuàng)建自定義opener對象;
使用自定義的opener對象,調(diào)用open()方法發(fā)送請求。
如果程序里所有的請求都使用自定義的opener,可以使用urllib2.install_opener() 將自定義的 opener 對象 定義為 全局opener,表示如果之后凡是調(diào)用urlopen,都將使用這個opener(根據(jù)自己的需求來選擇)
6)利用代理來定義opener
ProxyHandler處理器(代理設(shè)置)
urllib2中通過ProxyHandler來設(shè)置使用代理服務(wù)器,下面代碼說明如何使用自定義opener來使用代理:
import urllib2
#構(gòu)建了兩個代理Handler,一個有代理IP,一個沒有代理IP
httpproxy_handler = urllib2.ProxyHandler({"http" : "124.88.67.81:80"})
nullproxy_handler = urllib2.ProxyHandler({})
proxySwitch = True #定義一個代理開關(guān)
#通過 urllib2.build_opener()方法使用這些代理Handler對象,創(chuàng)建自定義opener對象
#根據(jù)代理開關(guān)是否打開,使用不同的代理模式
if proxySwitch:
opener = urllib2.build_opener(httpproxy_handler)
else:
opener = urllib2.build_opener(nullproxy_handler)
request = urllib2.Request("http://www.baidu.com/")
#1. 如果這么寫,只有使用opener.open()方法發(fā)送請求才使用自定義的代理,而urlopen()則不使用自定義代理。
response = opener.open(request)
#2. 如果這么寫,就是將opener應用到全局,之后所有的,不管是opener.open()還是urlopen() 發(fā)送請求,都將使用自定義代理。
#urllib2.install_opener(opener)
#response = urlopen(request)
print response.read()
開放代理的使用:
免費短期代理網(wǎng)站舉例:
西刺免費代理IP
快代理免費代理
Proxy360代理
全網(wǎng)代理IP
如果代理IP足夠多,就可以像隨機獲取User-Agent一樣,隨機選擇一個代理去訪問網(wǎng)站。
import urllib2
import random
proxy_list = [
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"},
{"http" : "124.88.67.81:80"}
]
#隨機選擇一個代理
proxy = random.choice(proxy_list)
#使用選擇的代理構(gòu)建代理處理器對象
httpproxy_handler = urllib2.ProxyHandler(proxy)
opener = urllib2.build_opener(httpproxy_handler)
request = urllib2.Request("http://www.baidu.com/")
response = opener.open(request)
print response.read()
但是,這些免費開放代理一般會有很多人都在使用,而且代理有壽命短,速度慢,匿名度不高,HTTP/HTTPS支持不穩(wěn)定等缺點(免費沒好貨)。
所以,專業(yè)爬蟲工程師或爬蟲公司會使用高品質(zhì)的私密代理。
私密代理:
====HTTPPasswordMgrWithDefaultRealm()
HTTPPasswordMgrWithDefaultRealm()類將創(chuàng)建一個密碼管理對象,用來保存 HTTP 請求相關(guān)的用戶名和密碼,主要應用兩個場景:
驗證代理授權(quán)的用戶名和密碼 (ProxyBasicAuthHandler())
驗證Web客戶端的的用戶名和密碼 (HTTPBasicAuthHandler())
示例:
import urllib
import urllib2
#用戶名
user = "test"
#密碼
passwd = "123456"
#Web服務(wù)器 IP
webserver = "http://192.168.199.107"
#構(gòu)建一個密碼管理對象,用來保存需要處理的用戶名和密碼
passwdmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
#添加賬戶信息,第一個參數(shù)realm是與遠程服務(wù)器相關(guān)的域信息,一般沒人管它都是寫None,后面三個參數(shù)分別是 Web服務(wù)器、用戶名、密碼
passwdmgr.add_password(None, webserver, user, passwd)
#構(gòu)建一個HTTP基礎(chǔ)用戶名/密碼驗證的HTTPBasicAuthHandler處理器對象,參數(shù)是創(chuàng)建的密碼管理對象
httpauth_handler = urllib2.HTTPBasicAuthHandler(passwdmgr)
#通過 build_opener()方法使用這些代理Handler對象,創(chuàng)建自定義opener對象,參數(shù)包括構(gòu)建的 proxy_handler
opener = urllib2.build_opener(httpauth_handler)
#可以選擇通過install_opener()方法定義opener為全局opener
urllib2.install_opener(opener)
#構(gòu)建 Request對象
request = urllib2.Request("http://192.168.199.107")
#定義opener為全局opener后,可直接使用urlopen()發(fā)送請求
response = urllib2.urlopen(request)
#打印響應內(nèi)容
print response.read()
7)Cookie:
HTTP是無狀態(tài)的面向連接的協(xié)議, 為了保持連接狀態(tài), 引入了Cookie機制 Cookie是http消息頭中的一種屬性,包括:
Cookie名字(Name)
Cookie的值(Value)
Cookie的過期時間(Expires/Max-Age)
Cookie作用路徑(Path)
Cookie所在域名(Domain),
使用Cookie進行安全連接(Secure)。
前兩個參數(shù)是Cookie應用的必要條件,另外,還包括Cookie大?。⊿ize,不同瀏覽器對Cookie個數(shù)及大小限制是有差異的)。
Cookie由變量名和值組成,根據(jù) Netscape公司的規(guī)定,Cookie格式如下:
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE
(2)Cookie應用
Cookies在爬蟲方面最典型的應用是判定注冊用戶是否已經(jīng)登錄網(wǎng)站,用戶可能會得到提示,是否在下一次進入此網(wǎng)站時保留用戶信息以便簡化登錄手續(xù)。
示例一:
import urllib2
#構(gòu)建一個已經(jīng)登錄過的用戶的headers信息
headers = {
"Host":"www.renren.com",
"Connection":"keep-alive",
"Upgrade-Insecure-Requests":"1",
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8",
"Accept-Language":"zh-CN,zh;q=0.8,en;q=0.6",
#便于終端閱讀,表示不支持壓縮文件
#Accept-Encoding: gzip, deflate, sdch,
#重點:這個Cookie是保存了密碼無需重復登錄的用戶的Cookie,這個Cookie里記錄了用戶名,密碼(通常經(jīng)過RAS加密)
"Cookie": "anonymid=ixrna3fysufnwv; depovince=GW; _r01_=1; JSESSIONID=abcmaDhEdqIlM7riy5iMv; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484060607173; jebecookies=26fb58d1-cbe7-4fc3-a4ad-592233d1b42e|||||; ick_login=1f2b895d-34c7-4a1d-afb7-d84666fad409; _de=BF09EE3A28DED52E6B65F6A4705D973F1383380866D39FF5; p=99e54330ba9f910b02e6b08058f780479; ap=327550029; first_login_flag=1; ln_uact=mr_mao_hacker@163.com; ln_hurl=http://hdn.xnimg.cn/photos/hdn521/20140529/1055/h_main_9A3Z_e0c300019f6a195a.jpg; t=214ca9a28f70ca6aa0801404dda4f6789; societyguester=214ca9a28f70ca6aa0801404dda4f6789; id=327550029; xnsid=745033c5; ver=7.0; loginfrom=syshome"
}
#2. 通過headers里的報頭信息(主要是Cookie信息),構(gòu)建Request對象
urllib2.Request("http://www.renren.com/", headers = headers)
#3. 直接訪問renren主頁,服務(wù)器會根據(jù)headers報頭信息(主要是Cookie信息),判斷這是一個已經(jīng)登錄的用戶,并返回相應的頁面
response = urllib2.urlopen(request)
#4. 打印響應內(nèi)容
print response.read()
但是這樣做太過復雜,我們先需要在瀏覽器登錄賬戶,并且設(shè)置保存密碼,并且通過抓包才能獲取這個Cookie,那有么有更簡單方便的方法呢?
示例二:
cookielib 庫
該模塊主要的對象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。
CookieJar:管理HTTP cookie值、存儲HTTP請求生成的cookie、向傳出的HTTP請求添加cookie的對象。整個cookie都存儲在內(nèi)存中,對CookieJar實例進行垃圾回收后cookie也將丟失。
FileCookieJar (filename,delayload=None,policy=None):從CookieJar派生而來,用來創(chuàng)建FileCookieJar實例,檢索cookie信息并將cookie存儲到文件中。filename是存儲cookie的文件名。delayload為True時支持延遲訪問訪問文件,即只有在需要時才讀取文件或在文件中存儲數(shù)據(jù)。
MozillaCookieJar (filename,delayload=None,policy=None):從FileCookieJar派生而來,創(chuàng)建與Mozilla瀏覽器 cookies.txt兼容的FileCookieJar實例。
LWPCookieJar (filename,delayload=None,policy=None):從FileCookieJar派生而來,創(chuàng)建與libwww-perl標準的 Set-Cookie3 文件格式兼容的FileCookieJar實例。
其實大多數(shù)情況下,我們只用CookieJar(),如果需要和本地文件交互,就用 MozillaCookjar() 或 LWPCookieJar()
利用利用cookielib和post登錄人人網(wǎng)
import urllib
import urllib2
import cookielib
#構(gòu)建一個CookieJar對象實例來保存cookie
cookie = cookielib.CookieJar()
#2. 使用HTTPCookieProcessor()來創(chuàng)建cookie處理器對象,參數(shù)為CookieJar()對象
cookie_handler = urllib2.HTTPCookieProcessor(cookie)
#3. 通過 build_opener() 來構(gòu)建opener
opener = urllib2.build_opener(cookie_handler)
#4. addheaders 接受一個列表,里面每個元素都是一個headers信息的元祖, opener將附帶headers信息
opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36")]
#5. 需要登錄的賬戶和密碼
data = {"email":"mr_mao_hacker@163.com", "password":"alaxxxxxime"}
#6. 通過urlencode()轉(zhuǎn)碼
postdata = urllib.urlencode(data)
#7. 構(gòu)建Request請求對象,包含需要發(fā)送的用戶名和密碼
request = urllib2.Request("http://www.renren.com/PLogin.do", data = postdata)
#8. 通過opener發(fā)送這個請求,并獲取登錄后的Cookie值,
opener.open(request)
#9. opener包含用戶登錄后的Cookie值,可以直接訪問那些登錄后才可以訪問的頁面
response = opener.open("http://www.renren.com/410043129/profile")
#10. 打印響應內(nèi)容
print response.read()
模擬登錄要注意幾點:
登錄一般都會先有一個HTTP GET,用于拉取一些信息及獲得Cookie,然后再HTTP POST登錄。
(1)HTTP POST登錄的鏈接有可能是動態(tài)的,從GET返回的信息中獲取。
(2)password 有些是明文發(fā)送,有些是加密后發(fā)送。有些網(wǎng)站甚至采用動態(tài)加密的,同時包括了很多其他數(shù)據(jù)的加密(3)信息,只能通過查看JS源碼獲得加密算法,再去破解加密,非常困難。
(4)大多數(shù)網(wǎng)站的登錄整體流程是類似的,可能有些細節(jié)不一樣,所以不能保證其他網(wǎng)站登錄成功。
8)urllib2 的異常錯誤處理
URLError 產(chǎn)生的原因主要有:
(1)沒有網(wǎng)絡(luò)連接
(2)服務(wù)器連接失敗
(3)找不到指定的服務(wù)器
我們可以用try except語句來捕獲相應的異常。下面的例子里我們訪問了一個不存在的域名:
#urllib2_urlerror.py
import urllib2
requset = urllib2.Request('http://www.ajkfhafwjqh.com')
try:
urllib2.urlopen(request, timeout=5)
except urllib2.URLError, err:
print err
HTTPError
HTTPError是URLError的子類,我們發(fā)出一個請求時,服務(wù)器上都會對應一個response應答對象,其中它包含一個數(shù)字"響應狀態(tài)碼"。
如果urlopen或opener.open不能處理的,會產(chǎn)生一個HTTPError,對應相應的狀態(tài)碼,HTTP狀態(tài)碼表示HTTP協(xié)議所返回的響應的狀態(tài)。
注意,urllib2可以為我們處理重定向的頁面(也就是3開頭的響應碼),100-299范圍的號碼表示成功,所以我們只能看到400-599的錯誤號碼。
----------------改進版
由于HTTPError的父類是URLError,所以父類的異常應當寫到子類異常的后面,所以上述的代碼可以這么改寫:
#urllib2_botherror.py
import urllib2
requset = urllib2.Request('http://blog.baidu.com/itcast')
try:
urllib2.urlopen(requset)
except urllib2.HTTPError, err:
print err.code
except urllib2.URLError, err:
print err
else:
print "Good Job"-------------------------------------------------------
2 Requests模塊
Requests 繼承了urllib2的所有特性。Requests支持HTTP連接保持和連接池,支持使用cookie保持會話,支持文件上傳,支持自動確定響應內(nèi)容的編碼,支持國際化的 URL 和 POST 數(shù)據(jù)自動編碼。
requests 的底層實現(xiàn)其實就是 urllib3
Requests的文檔非常完備,中文文檔也相當不錯。Requests能完全滿足當前網(wǎng)絡(luò)的需求,支持Python 2.6—3.5,而且能在PyPy下完美運行。
開源地址:https://github.com/kennethreitz/requests
中文文檔 API: http://docs.python-requests.org/zh_CN/latest/index.html
GET請求:
(1)最基本的GET請求可以直接用get方法
response = requests.get("http://www.baidu.com/")
#也可以這么寫
#response = requests.request("get", "http://www.baidu.com/")
(2)添加 headers 和 查詢參數(shù)
如果想添加 headers,可以傳入headers參數(shù)來增加請求頭中的headers信息。如果要將參數(shù)放在url中傳遞,可以利用 params 參數(shù)。
import requests
kw = {'wd':'長城'}
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
#params 接收一個字典或者字符串的查詢參數(shù),字典類型自動轉(zhuǎn)換為url編碼,不需要urlencode()
response = requests.get("http://www.baidu.com/s?", params = kw, headers = headers)
#查看響應內(nèi)容,response.text 返回的是Unicode格式的數(shù)據(jù)
print response.text
#查看響應內(nèi)容,response.content返回的字節(jié)流數(shù)據(jù)
print respones.content
#查看完整url地址
print response.url
#查看響應頭部字符編碼
print response.encoding
#查看響應碼
print response.status_code
POST請求:
(1)最基本的GET請求可以直接用post方法
response = requests.post("http://www.baidu.com/", data = data)
(2)傳入data數(shù)據(jù)
對于 POST 請求來說,我們一般需要為它增加一些參數(shù)。那么最基本的傳參方法可以利用 data 這個參數(shù)。
import requests
formdata = {
"type":"AUTO",
"i":"i love python",
"doctype":"json",
"xmlVersion":"1.8",
"keyfrom":"fanyi.web",
"ue":"UTF-8",
"action":"FY_BY_ENTER",
"typoResult":"true"
}
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"
headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
response = requests.post(url, data = formdata, headers = headers)
print response.text
#如果是json文件可以直接顯示
print response.json()
代理(proxies參數(shù))
如果需要使用代理,你可以通過為任意請求方法提供 proxies 參數(shù)來配置單個請求:
import requests
#根據(jù)協(xié)議類型,選擇不同的代理
proxies = {
"http": "http://12.34.56.79:9527",
"https": "http://12.34.56.79:9527",
}
response = requests.get("http://www.baidu.com", proxies = proxies)
print response.text
也可以通過本地環(huán)境變量 HTTP_PROXY 和 HTTPS_PROXY 來配置代理:
export HTTP_PROXY="http://12.34.56.79:9527"
export HTTPS_PROXY="https://12.34.56.79:9527"
私密代理驗證(特定格式) 和 Web客戶端驗證(auth 參數(shù))
urllib2 這里的做法比較復雜,requests只需要一步:
私密代理
import requests
#如果代理需要使用HTTP Basic Auth,可以使用下面這種格式:
proxy = { "http": "mr_mao_hacker:sffqry9r@61.158.163.130:16816" }
response = requests.get("http://www.baidu.com", proxies = proxy)
print response.text
web客戶端驗證
如果是Web客戶端驗證,需要添加 auth = (賬戶名, 密碼)
import requests
auth=('test', '123456')
response = requests.get('http://192.168.199.107', auth = auth)
print response.text
Cookies 和 Sission
Cookies
如果一個響應中包含了cookie,那么我們可以利用 cookies參數(shù)拿到:
import requests
response = requests.get("http://www.baidu.com/")
#返回CookieJar對象:
cookiejar = response.cookies
#將CookieJar轉(zhuǎn)為字典:
cookiedict = requests.utils.dict_from_cookiejar(cookiejar)
print cookiejar
print cookiedict
運行結(jié)果:
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
{'BDORZ': '27315'}
Sission
在 requests 里,session對象是一個非常常用的對象,這個對象代表一次用戶會話:從客戶端瀏覽器連接服務(wù)器開始,到客戶端瀏覽器與服務(wù)器斷開。
會話能讓我們在跨請求時候保持某些參數(shù),比如在同一個 Session 實例發(fā)出的所有請求之間保持 cookie 。
實現(xiàn)人人網(wǎng)登錄
import requests
#1. 創(chuàng)建session對象,可以保存Cookie值
ssion = requests.session()
#2. 處理 headers
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
#3. 需要登錄的用戶名和密碼
data = {"email":"mr_mao_hacker@163.com", "password":"alarmchime"}
#4. 發(fā)送附帶用戶名和密碼的請求,并獲取登錄后的Cookie值,保存在ssion里
ssion.post("http://www.renren.com/PLogin.do", data = data)
#5. ssion包含用戶登錄后的Cookie值,可以直接訪問那些登錄后才可以訪問的頁面
response = ssion.get("http://www.renren.com/410043129/profile")
#6. 打印響應內(nèi)容
print response.text
處理HTTPS請求 SSL證書驗證
Requests也可以為HTTPS請求驗證SSL證書:
要想檢查某個主機的SSL證書,你可以使用 verify 參數(shù)(也可以不寫)
import requests
response = requests.get("https://www.baidu.com/", verify=True)
#也可以省略不寫
#response = requests.get("https://www.baidu.com/")
print r.text
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。