爬蟲涉及的知識體系

一爬蟲的定義:
所謂爬蟲就是指:可以獲取網頁信息的程序
又分爲通用爬蟲和聚焦爬蟲
1)通用爬蟲:從互聯網中搜集網頁,採集信息,這些網頁信息用於爲搜索引擎建立索引從而提供支持,它決定着整個引擎系統的內容是否豐富,信息是否即時,因此其性能的優劣直接影響着搜索引擎的效果。
抓取流程:
爬蟲涉及的知識體系
除了HTML文件外,搜索引擎通常還能抓取和索引以文字爲基礎的多種文件類型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我們在搜索結果中也經常會看到這些文件類型。
搜索引擎還不能處理圖片、視頻、Flash 這類非文字內容,也不能執行腳本和程序。
但是,這些通用性搜索引擎也存在着一定的侷限性:
(1)通用搜索引擎所返回的結果都是網頁,而大多情況下,網頁裏90%的內容對用戶來說都是無用的。
(2)不同領域、不同背景的用戶往往具有不同的檢索目的和需求,搜索引擎無法提供針對具體某個用戶的搜索結果。
(3)萬維網數據形式的豐富和網絡技術的不斷髮展,圖片、數據庫、音頻、視頻多媒體等不同數據大量出現,通用搜索引擎對這些文件無能爲力,不能很好地發現和獲取。
(4)通用搜索引擎大多提供基於關鍵字的檢索,難以支持根據語義信息提出的查詢,無法準確理解用戶的具體需求。

2)聚焦爬蟲
聚焦爬蟲,是"面向特定主題需求"的一種網絡爬蟲程序,它與通用搜索引擎爬蟲的區別在於: 聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,儘量保證只抓取與需求相關的網頁信息。

二瀏覽器發送HTTP請求的過程中涉及的部分內容:
1)當用戶在瀏覽器的地址欄中輸入一個URL並按回車鍵之後,瀏覽器會向HTTP服務器發送HTTP請求。HTTP請求主要分爲“Get”和“Post”兩種方法。
2)當我們在瀏覽器輸入URL http://www.baidu.com 的時候,瀏覽器發送一個Request請求去獲取 http://www.baidu.com 的html文件,服務器把Response文件對象發送回給瀏覽器。
3)瀏覽器分析Response中的 HTML,發現其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。 瀏覽器會自動再次發送Request去獲取圖片,CSS文件,或者JS文件。
4)當所有的文件都下載成功後,網頁會根據HTML語法結構,完整的顯示出來了。
URL(Uniform / Universal Resource Locator的縮寫):統一資源定位符,是用於完整地描述Internet上網頁和其他資源的地址的一種標識方法。
爬蟲涉及的知識體系
基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]

scheme:協議(例如:http, https, ftp)
host:服務器的IP地址或者域名
port#:服務器的端口(如果是走協議默認端口,缺省端口80)
path:訪問資源的路徑
query-string:參數,發送給http服務器的數據
anchor:錨(跳轉到網頁的指定錨點位置)
例如:
ftp://192.168.0.116:8080/index
http://www.baidu.com
http://item.jd.com/11936238.html#product-detail

5)HTTP請求主要分爲Get和Post兩種方法:
GET是從服務器上獲取數據,POST是向服務器傳送數據

GET請求參數顯示,都顯示在瀏覽器網址上,HTTP服務器根據該請求所包含URL中的參數來產生響應內容,即“Get”請求的參數是URL的一部分。 例如: http://www.baidu.com/s?wd=Chinese

POST請求參數在請求體當中,消息長度沒有限制而且以隱式的方式進行發送,通常用來向HTTP服務器提交量比較大的數據(比如請求中包含許多參數或者文件上傳操作等),請求的參數包含在“Content-Type”消息頭裏,指明該消息體的媒體類型和編碼,

注意:避免使用Get方式提交表單,因爲有可能會導致安全問題。 比如說在登陸表單中用Get方式,用戶輸入的用戶名和密碼將在地址欄中暴露無遺。

6)常用的請求報頭:
Host (主機和端口號)
Connection (鏈接類型)
Upgrade-Insecure-Requests (升級爲HTTPS請求)
User-Agent (瀏覽器名稱)
Accept (傳輸文件類型)
Referer (頁面跳轉處)
Accept-Encoding(文件編解碼格式)
Accept-Language(語言種類)
Accept-Charset(字符編碼)
Cookie (Cookie)
Content-Type (POST數據類型)

7)常用的響應報頭(瞭解)
Cache-Control:must-revalidate, no-cache, private。
這個值告訴客戶端,服務端不希望客戶端緩存資源,在下次請求資源時,必須要從新請求服務器,不能從緩存副本中獲取資源。
Connection:keep-alive
這個字段作爲迴應客戶端的Connection:keep-alive,告訴客戶端服務器的tcp連接也是一個長連接,客戶端可以繼續使用這個tcp連接發送http請求。
Content-Encoding:gzip
告訴客戶端,服務端發送的資源是採用gzip編碼的,客戶端看到這個信息後,應該採用gzip對資源進行解碼。
Content-Type:text/html;charset=UTF-8
告訴客戶端,資源文件的類型,還有字符編碼,客戶端通過utf-8對資源進行解碼,然後對資源進行html解析。通常我們會看到有些網站是亂碼的,往往就是服務器端沒有返回正確的編碼。
Date:Sun, 21 Sep 2016 06:18:21 GMT
這個是服務端發送資源時的服務器時間,GMT是格林尼治所在地的標準時間。http協議中發送的時間都是GMT的,這主要是解決在互聯網上,不同時區在相互請求資源的時候,時間混亂問題。
Expires:Sun, 1 Jan 2000 01:00:00 GMT
這個響應頭也是跟緩存有關的,告訴客戶端在這個時間前,可以直接訪問緩存副本,很顯然這個值會存在問題,因爲客戶端和服務器的時間不一定會都是相同的,如果時間不同就會導致問題。所以這個響應頭是沒有Cache-Control:max-age=*這個響應頭準確的,因爲max-age=date中的date是個相對時間,不僅更好理解,也更準確。
Pragma:no-cache
這個含義與Cache-Control等同。
Server:Tengine/1.4.6
這個是服務器和相對應的版本,只是告訴客戶端服務器的信息。
Transfer-Encoding:chunked
這個響應頭告訴客戶端,服務器發送的資源的方式是分塊發送的。一般分塊發送的資源都是服務器動態生成的,在發送時還不知道發送資源的大小,所以採用分塊發送,每一塊都是獨立的,獨立的塊都能標示自己的長度,最後一塊是0長度的,當客戶端讀到這個0長度的塊時,就可以確定資源已經傳輸完了。
Vary: Accept-Encoding
告訴緩存服務器,緩存壓縮文件和非壓縮文件兩個版本,現在這個字段用處並不大,因爲現在的瀏覽器都是支持壓縮的。

8)響應狀態碼
響應狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。

常見狀態碼:
100~199:表示服務器成功接收部分請求,要求客戶端繼續提交其餘請求才能完成整個處理過程。
200~299:表示服務器成功接收請求並已完成整個處理過程。常用200(OK 請求成功)。
300~399:爲完成請求,客戶需進一步細化請求。例如:請求的資源已經移動一個新地址、常用302(所請求的頁面已經臨時轉移至新的url)、307和304(使用緩存資源)。
400~499:客戶端的請求有錯誤,常用404(服務器無法找到被請求的頁面)、403(服務器拒絕訪問,權限不夠)。
500~599:服務器端出現錯誤,常用500(請求未完成。服務器遇到不可預知的情況)。

9)Cookie 和 Session:
服務器和客戶端的交互僅限於請求/響應過程,結束之後便斷開,在下一次請求時,服務器會認爲新的客戶端。
爲了維護他們之間的鏈接,讓服務器知道這是前一個用戶發送的請求,必須在一個地方保存客戶端的信息。

Cookie:通過在 客戶端 記錄的信息確定用戶的身份。
Session:通過在 服務器端 記錄的信息確定用戶的身份。

三 爬蟲程序中常用的幾個庫
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()方法的參數,構造並返回一個Request對象
request = urllib2.Request("http://www.baidu.com")
#Request對象作爲urlopen()方法的參數,發送給服務器並接收響應
response = urllib2.urlopen(request)
html = response.read()
print html

3)新建Request實例,除了必須要有 url 參數之外,還可以設置另外兩個參數:
data(默認空):是伴隨 url 提交的數據(比如要post的數據),同時 HTTP 請求將從 "GET"方式 改爲 "POST"方式。

headers(默認空):是一個字典,包含了需要發送的HTTP報頭的鍵值對。
這兩個參數下面會說到。

User-Agent
但是如果我們用一個合法的身份去請求別人網站,顯然人家就是歡迎的,所以我們就應該給我們的這個代碼加上一個身份,就是所謂的User-Agent頭。

瀏覽器 就是互聯網世界上公認被允許的身份,如果我們希望我們的爬蟲程序更像一個真實用戶,那我們第一步,就是需要僞裝成一個被公認的瀏覽器。用不同的瀏覽器在發送請求的時候,會有不同的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)

#也可以通過調用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請求的相關模塊,但是提供了不同的功能。兩個最顯著的不同如下:
urllib 僅可以接受URL,不能創建 設置了headers 的Request 類實例;

    但是 urllib 提供 urlencode 方法用來GET查詢字符串的產生,而 urllib2 則沒有。(這是 urllib 和 urllib2 經常一起使用的主要原因)

編碼工作使用urllib的urlencode()函數,幫我們將key:value這樣的鍵值對轉換成"key=value"這樣的字符串,解碼工作可以使用urllib的unquote()函數。(注意,不是urllib2.urlencode() )

一般HTTP請求提交數據,需要編碼成 URL編碼格式,然後做爲url的一部分,或者作爲參數傳到Request對象中。

Get方式:
GET請求一般用於我們向服務器獲取數據,比如說,我們用百度搜索傳智播客:https://www.baidu.com/s?wd=傳智播客

5)Handler處理器 和 自定義Opener
opener是 urllib2.OpenerDirector 的實例,我們之前一直都在使用的urlopen,它是一個特殊的opener(也就是模塊幫我們構建好的)。

但是基本的urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高級功能。所以要支持這些功能:

用相關的 Handler處理器 來創建特定功能的處理器對象;
然後通過 urllib2.build_opener()方法使用這些處理器對象,創建自定義opener對象;
使用自定義的opener對象,調用open()方法發送請求。
如果程序裏所有的請求都使用自定義的opener,可以使用urllib2.install_opener() 將自定義的 opener 對象 定義爲 全局opener,表示如果之後凡是調用urlopen,都將使用這個opener(根據自己的需求來選擇)

6)利用代理來定義opener
ProxyHandler處理器(代理設置)

urllib2中通過ProxyHandler來設置使用代理服務器,下面代碼說明如何使用自定義opener來使用代理:
import urllib2

#構建了兩個代理Handler,一個有代理IP,一個沒有代理IP
httpproxy_handler = urllib2.ProxyHandler({"http" : "124.88.67.81:80"})
nullproxy_handler = urllib2.ProxyHandler({})

proxySwitch = True #定義一個代理開關

#通過 urllib2.build_opener()方法使用這些代理Handler對象,創建自定義opener對象
#根據代理開關是否打開,使用不同的代理模式
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()方法發送請求才使用自定義的代理,而urlopen()則不使用自定義代理。
response = opener.open(request)

#2. 如果這麼寫,就是將opener應用到全局,之後所有的,不管是opener.open()還是urlopen() 發送請求,都將使用自定義代理。
#urllib2.install_opener(opener)
#response = urlopen(request)
print response.read()


開放代理的使用:
免費短期代理網站舉例:

西刺免費代理IP
快代理免費代理
Proxy360代理
全網代理IP
如果代理IP足夠多,就可以像隨機獲取User-Agent一樣,隨機選擇一個代理去訪問網站。

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)
#使用選擇的代理構建代理處理器對象
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支持不穩定等缺點(免費沒好貨)。

所以,專業爬蟲工程師或爬蟲公司會使用高品質的私密代理。


私密代理:
====HTTPPasswordMgrWithDefaultRealm()
HTTPPasswordMgrWithDefaultRealm()類將創建一個密碼管理對象,用來保存 HTTP 請求相關的用戶名和密碼,主要應用兩個場景:

驗證代理授權的用戶名和密碼 (ProxyBasicAuthHandler())
驗證Web客戶端的的用戶名和密碼 (HTTPBasicAuthHandler())

示例:
import urllib
import urllib2

#用戶名
user = "test"
#密碼
passwd = "123456"
#Web服務器 IP
webserver = "http://192.168.199.107"

#構建一個密碼管理對象,用來保存需要處理的用戶名和密碼
passwdmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

#添加賬戶信息,第一個參數realm是與遠程服務器相關的域信息,一般沒人管它都是寫None,後面三個參數分別是 Web服務器、用戶名、密碼
passwdmgr.add_password(None, webserver, user, passwd)

#構建一個HTTP基礎用戶名/密碼驗證的HTTPBasicAuthHandler處理器對象,參數是創建的密碼管理對象
httpauth_handler = urllib2.HTTPBasicAuthHandler(passwdmgr)

#通過 build_opener()方法使用這些代理Handler對象,創建自定義opener對象,參數包括構建的 proxy_handler
opener = urllib2.build_opener(httpauth_handler)

#可以選擇通過install_opener()方法定義opener爲全局opener
urllib2.install_opener(opener)

#構建 Request對象
request = urllib2.Request("http://192.168.199.107")

#定義opener爲全局opener後,可直接使用urlopen()發送請求
response = urllib2.urlopen(request)

#打印響應內容
print response.read()

7)Cookie:
HTTP是無狀態的面向連接的協議, 爲了保持連接狀態, 引入了Cookie機制 Cookie是http消息頭中的一種屬性,包括:

Cookie名字(Name)
Cookie的值(Value)
Cookie的過期時間(Expires/Max-Age)
Cookie作用路徑(Path)
Cookie所在域名(Domain),
使用Cookie進行安全連接(Secure)。

前兩個參數是Cookie應用的必要條件,另外,還包括Cookie大小(Size,不同瀏覽器對Cookie個數及大小限制是有差異的)。
Cookie由變量名和值組成,根據 Netscape公司的規定,Cookie格式如下:

Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

(2)Cookie應用
Cookies在爬蟲方面最典型的應用是判定註冊用戶是否已經登錄網站,用戶可能會得到提示,是否在下一次進入此網站時保留用戶信息以便簡化登錄手續。

示例一:
import urllib2
#構建一個已經登錄過的用戶的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裏記錄了用戶名,密碼(通常經過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; [email protected]; 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信息),構建Request對象
urllib2.Request("http://www.renren.com/", headers = headers)

#3. 直接訪問renren主頁,服務器會根據headers報頭信息(主要是Cookie信息),判斷這是一個已經登錄的用戶,並返回相應的頁面
response = urllib2.urlopen(request)

#4. 打印響應內容
print response.read()

但是這樣做太過複雜,我們先需要在瀏覽器登錄賬戶,並且設置保存密碼,並且通過抓包才能獲取這個Cookie,那有麼有更簡單方便的方法呢?

示例二:
cookielib 庫
該模塊主要的對象有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

CookieJar:管理HTTP cookie值、存儲HTTP請求生成的cookie、向傳出的HTTP請求添加cookie的對象。整個cookie都存儲在內存中,對CookieJar實例進行垃圾回收後cookie也將丟失。

FileCookieJar (filename,delayload=None,policy=None):從CookieJar派生而來,用來創建FileCookieJar實例,檢索cookie信息並將cookie存儲到文件中。filename是存儲cookie的文件名。delayload爲True時支持延遲訪問訪問文件,即只有在需要時纔讀取文件或在文件中存儲數據。

MozillaCookieJar (filename,delayload=None,policy=None):從FileCookieJar派生而來,創建與Mozilla瀏覽器 cookies.txt兼容的FileCookieJar實例。

LWPCookieJar (filename,delayload=None,policy=None):從FileCookieJar派生而來,創建與libwww-perl標準的 Set-Cookie3 文件格式兼容的FileCookieJar實例。

其實大多數情況下,我們只用CookieJar(),如果需要和本地文件交互,就用 MozillaCookjar() 或 LWPCookieJar()

利用利用cookielib和post登錄人人網
import urllib
import urllib2
import cookielib

#構建一個CookieJar對象實例來保存cookie
cookie = cookielib.CookieJar()

#2. 使用HTTPCookieProcessor()來創建cookie處理器對象,參數爲CookieJar()對象
cookie_handler = urllib2.HTTPCookieProcessor(cookie)

#3. 通過 build_opener() 來構建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":"[email protected]", "password":"alaxxxxxime"}

#6. 通過urlencode()轉碼
postdata = urllib.urlencode(data)

#7. 構建Request請求對象,包含需要發送的用戶名和密碼
request = urllib2.Request("http://www.renren.com/PLogin.do", data = postdata)

#8. 通過opener發送這個請求,並獲取登錄後的Cookie值,
opener.open(request)

#9. opener包含用戶登錄後的Cookie值,可以直接訪問那些登錄後纔可以訪問的頁面
response = opener.open("http://www.renren.com/410043129/profile")

#10. 打印響應內容
print response.read()
模擬登錄要注意幾點:

登錄一般都會先有一個HTTP GET,用於拉取一些信息及獲得Cookie,然後再HTTP POST登錄。
(1)HTTP POST登錄的鏈接有可能是動態的,從GET返回的信息中獲取。
(2)password 有些是明文發送,有些是加密後發送。有些網站甚至採用動態加密的,同時包括了很多其他數據的加密(3)信息,只能通過查看JS源碼獲得加密算法,再去破解加密,非常困難。
(4)大多數網站的登錄整體流程是類似的,可能有些細節不一樣,所以不能保證其他網站登錄成功。

8)urllib2 的異常錯誤處理
URLError 產生的原因主要有:
(1)沒有網絡連接
(2)服務器連接失敗
(3)找不到指定的服務器
我們可以用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的子類,我們發出一個請求時,服務器上都會對應一個response應答對象,其中它包含一個數字"響應狀態碼"。

如果urlopen或opener.open不能處理的,會產生一個HTTPError,對應相應的狀態碼,HTTP狀態碼錶示HTTP協議所返回的響應的狀態。

注意,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保持會話,支持文件上傳,支持自動確定響應內容的編碼,支持國際化的 URL 和 POST 數據自動編碼。

requests 的底層實現其實就是 urllib3
Requests的文檔非常完備,中文文檔也相當不錯。Requests能完全滿足當前網絡的需求,支持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 和 查詢參數
如果想添加 headers,可以傳入headers參數來增加請求頭中的headers信息。如果要將參數放在url中傳遞,可以利用 params 參數。

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 接收一個字典或者字符串的查詢參數,字典類型自動轉換爲url編碼,不需要urlencode()
response = requests.get("http://www.baidu.com/s?", params = kw, headers = headers)

#查看響應內容,response.text 返回的是Unicode格式的數據
print response.text

#查看響應內容,response.content返回的字節流數據
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數據
對於 POST 請求來說,我們一般需要爲它增加一些參數。那麼最基本的傳參方法可以利用 data 這個參數。

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參數)
如果需要使用代理,你可以通過爲任意請求方法提供 proxies 參數來配置單個請求:

import requests

#根據協議類型,選擇不同的代理
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
也可以通過本地環境變量 HTTP_PROXY 和 HTTPS_PROXY 來配置代理:

export HTTP_PROXY="http://12.34.56.79:9527"
export HTTPS_PROXY="https://12.34.56.79:9527"

私密代理驗證(特定格式) 和 Web客戶端驗證(auth 參數)
urllib2 這裏的做法比較複雜,requests只需要一步:

私密代理
import requests
#如果代理需要使用HTTP Basic Auth,可以使用下面這種格式:
proxy = { "http": "mr_mao_hacker:[email protected]: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參數拿到:

import requests
response = requests.get("http://www.baidu.com/")

#返回CookieJar對象:
cookiejar = response.cookies

#將CookieJar轉爲字典:
cookiedict = requests.utils.dict_from_cookiejar(cookiejar)

print cookiejar
print cookiedict
運行結果:

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
{'BDORZ': '27315'}

Sission
在 requests 裏,session對象是一個非常常用的對象,這個對象代表一次用戶會話:從客戶端瀏覽器連接服務器開始,到客戶端瀏覽器與服務器斷開。
會話能讓我們在跨請求時候保持某些參數,比如在同一個 Session 實例發出的所有請求之間保持 cookie 。

實現人人網登錄
import requests

#1. 創建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":"[email protected]", "password":"alarmchime"}

#4. 發送附帶用戶名和密碼的請求,並獲取登錄後的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. 打印響應內容
print response.text


處理HTTPS請求 SSL證書驗證
Requests也可以爲HTTPS請求驗證SSL證書:

要想檢查某個主機的SSL證書,你可以使用 verify 參數(也可以不寫)
import requests
response = requests.get("https://www.baidu.com/", verify=True)

#也可以省略不寫
#response = requests.get("https://www.baidu.com/")
print r.text

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章