tenliu的爬蟲-requests學(xué)習(xí)

通過以上學(xué)習(xí),爬蟲算是入門了,掌握urllib、urllib2我們已經(jīng)具備了可以抓取網(wǎng)上大部分頁面的能力了。
但是我們前面也已經(jīng)講了urllib和urllib2的槽點(diǎn),可以用來做爬蟲,但是比較不便,有點(diǎn)違背python的主旨了。
這里介紹 python的第三方庫:requests

requests概述

requests官方slogan是這樣一句話:

Requests is the only Non-GMO HTTP library for Python, safe for human consumption.

針對誰不言而喻,urllib和urllib2的槽點(diǎn)太多,這不必說。問題是requests是否有吐槽他們的資格呢,它到底有多便利?

Requests 完全滿足今日 web 的需求:

  • Keep-Alive & 連接池
  • 國際化域名和 URL
  • 帶持久 Cookie 的會話
  • 瀏覽器式的 SSL 認(rèn)證
  • 自動內(nèi)容解碼
  • 基本/摘要式的身份認(rèn)證
  • 優(yōu)雅的 key/value Cookie
  • 自動解壓
  • Unicode 響應(yīng)體
  • HTTP(S) 代理支持
  • 文件分塊上傳
  • 流下載
  • 連接超時(shí)
  • 分塊請求
  • 支持 .netrc

requests安裝

requests庫并非出自python基金會,一般安裝python后不會自帶requests,使用時(shí)需要安裝:

pip install requests

requests類和方法

requests發(fā)展至今,功能上有很大擴(kuò)展,類和方法也是很多。這里主要將一些爬蟲常用的,希望兼顧實(shí)用和全面。

requests.Response類

requests的響應(yīng)類。

屬性 說明
encoding requests從響應(yīng)的header自動猜測出響應(yīng)頁面編碼方式
apparent_encoding requests從響應(yīng)頁面猜測響應(yīng)頁面編碼方式
url 響應(yīng)的url
status_code 響應(yīng)的http狀態(tài)碼
cookies 響應(yīng)的cookies
elapsed 發(fā)送請求到收到響應(yīng)消耗的時(shí)間
headers 響應(yīng)的headers
history 請求歷史
headers 響應(yīng)的headers
content 頁面源碼,str
text 也是頁面源碼,unicode,requests自動解碼

這里需要注意的是,不少人使用requests都有亂碼的困擾,就是因?yàn)樯厦鎸傩詂ontent和text沒搞清楚的問題,以后單獨(dú)講講這個問題。

requests.Session類

提供cookie持久性、連接池和配置。
requests提供的一個會話類,可以使用在爬蟲抓取時(shí)需要保持登錄狀態(tài)的情況

七個請求方法

如下六個請求方法:

  • requests.get(url, params=None, **kwargs)

  • requests.post(url, data=None, json=None, **kwargs)

  • requests.head(url, **kwargs)

  • requests.put(url, data=None, **kwargs)

  • requests.patch(url, data=None, **kwargs)

  • requests.delete(url, **kwargs)

    ?

    還有一個:

    ?

  • requests.request(method, url, **kwargs)

以上就是requests全部的訪問方法,并且全部都返回Request對象。
有點(diǎn)被嚇到了,那么我們僅僅使用

requests.get(url, params=None, **kwargs)
requests.post(url, data=None, json=None, **kwargs)

這兩個即可,分別是get請求和post請求,其他的在爬蟲中使用率不高。

請求參數(shù)**kwargs

參數(shù) 說明
params 自動構(gòu)建url,get請求時(shí)使用
data 提交表單,post請求時(shí)使用
headers 請求headers
cookies 請求cookies
timeout 超時(shí)時(shí)間
proxies ip代理
json 發(fā)送json
file 發(fā)送文件(Multipart-Encoded)
allow_redirects
auth
verify
stream
cert

requests實(shí)例講解

get方法-基本

這里我們看requests發(fā)送get方法的例子,并打印requests.Response的各個屬性看看

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
import requests
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
def first():
    #基本get方法,認(rèn)識request對象
    url = "http://www.tenliu.top/index.php/httpclient/"
    resp = requests.get(url)
    print resp.url
    print resp.encoding
    print resp.apparent_encoding
    print resp.headers
    print resp.cookies
    print resp.elapsed
    print resp.status_code
    print resp.ok
    print resp.reason
    print resp.history
    print resp.text
    print resp.content
if __name__=="__main__":
    first()

尷尬了,頁面

get請求-自動構(gòu)建url請求參數(shù)

requests.get()的params參數(shù),我們上面也說了,可以自動把params參數(shù)拼接在url中。當(dāng)然你也可以手工構(gòu)建URL。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
import requests
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
def second():
    url = "http://www.tenliu.top/index.php/httpclient/"
    payload = {'country': '中國', 'ranking': 2}
    resp = requests.get(url,params=payload)
    print resp.text
if __name__=="__main__":
    second()

執(zhí)行,打印頁面源碼,我們看到get請求參數(shù)傳遞成功。

var res = {"headers":{"HTTP_CONNECTION":"keep-alive","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_ACCEPT":"/","HTTP_USER_AGENT":"python-requests/2.11.1","REQUEST_METHOD":"GET"}, "params":{"country":"\u4e2d\u56fd","ranking":"2"}};

同時(shí),這里我們注意到requests再也不用urlencode編碼啦。urllib和urllib2慚不慚愧。
爬蟲-urllib2學(xué)習(xí)

post方法

requests.post()中data用來post參數(shù)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
import requests
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
def thrid():
    url = "http://www.tenliu.top/index.php/httpclient/"
    data = {'country': '中國', 'ranking': 2}
    resp = requests.post(url,data=data)
    print resp.text
if __name__=="__main__":
    thrid()

執(zhí)行打印頁面源碼,可以看到post方式傳遞參數(shù)成功:

var res = {"headers":{"HTTP_CONNECTION":"keep-alive","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_ACCEPT":"/","HTTP_USER_AGENT":"python-requests/2.11.1","REQUEST_METHOD":"POST"}, "params":{"country":"\u4e2d\u56fd","ranking":"2"}};

偽裝headers

以上的爬蟲都是沒有偽裝的,看看之前例子的執(zhí)行結(jié)果中:
"HTTP_USER_AGENT":"python-requests/2.18.4"

USER_AGENT是python-requests/2.18.4(我安裝的是2.18.4版本),明確告訴服務(wù)器自己爬蟲的身份了,被ban也是活該啦。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
import requests
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
def fourth():
    url = "http://www.tenliu.top/index.php/httpclient/"
    data = {'country': '中國', 'ranking': 2}
    headers = {
        'Cookie':'sugstore=1; type=test',
        'User-Agent':'Mozilla/5.0  test',
    }
    resp = requests.post(url,data=data,headers=headers)
    print resp.text 
if __name__=="__main__":
    fourth()

執(zhí)行打印源碼,可以看到偽裝成功。

var res = {"headers":{"HTTP_CONNECTION":"keep-alive","HTTP_ACCEPT_ENCODING":"gzip, deflate","HTTP_ACCEPT":"/","HTTP_USER_AGENT":"Mozilla/5.0 test","HTTP_COOKIE":"sugstore=1; type=test","REQUEST_METHOD":"POST"},"params":{"country":"\u4e2d\u56fd","ranking":"2"}};

ip代理

這里我們使用ip代理抓取頁面:
http://tool.chinaz.com/

至于為什么不抓取http://www.tenliu.top/index.php/httpclient/
這個頁面是chunked編碼傳輸內(nèi)容,添加ip代理抓取處理比較麻煩,不是這里要講的內(nèi)容)

我自己構(gòu)建了一個ip代理池,定時(shí)驗(yàn)證。這里有一個ip代理的展示頁面。可以從這里獲取ip代理

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
import requests
from lxml import etree
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
def fifth():
    url = 'http://tool.chinaz.com/'
    proxy = "121.196.226.246:84"
    proxies = {
        "http": "http://"+proxy,
        "https": "http://"+proxy,
    }
    resp = requests.get(url,proxies=proxies,timeout=32)
    print etree.HTML(resp.text).xpath('//div[@class="Mnav-left fl"]')[0].xpath('string(.)')
if __name__=="__main__":
    fifth()

執(zhí)行結(jié)果如下

IP查詢 - 您的 IP:121.196.226.246 來自:浙江省杭州市 阿里巴巴網(wǎng)絡(luò)有限公司

上面例子中有

from lxml import etree

print etree.HTML(resp.text).xpath('//div[@class="Mnav-left fl"]')[0].xpath('string(.)')

這里涉及到頁面提取的xpath語法,和python對xpath的支持包lxml,也不是這里講的內(nèi)容,下一篇會單獨(dú)說說“頁面解析”,這也是爬蟲很重要的內(nèi)容。

session

下面是session的簡單例子,更詳細(xì)的用法還要在實(shí)際應(yīng)用中施展。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib
import urllib2
import requests
from lxml import etree
import sys
reload(sys) 
sys.setdefaultencoding('utf8')
def sixth():
    #session
    url = "http://www.tenliu.top/index.php/httpclient/"
    s = requests.Session()
    resp = s.get(url)
    print resp.text
if __name__=="__main__":
    sixth()

這個例子當(dāng)然很簡單,更具體的使用場景是:
在抓取需要登錄信息的頁面時(shí),如果沒有session,只能保存cookies,在每次抓取時(shí)都發(fā)送cookies。但是使用session,登錄后可以不用考慮cookies了。

先到這里吧,以后再說頁面提取。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容