- 基本爬蟲知識python庫urllib、urllib2、requests
- urllib、urllib2、request三者關(guān)系
- 從python的urllib開始
- urllib2學(xué)習(xí)
- requests學(xué)習(xí)
- ps:如何用瀏覽器抓包分析
- ps:爬蟲分析小工具
- 頁面提取
- 正則表達(dá)式
- xpath
- beautifulsoup
- 動態(tài)頁面抓取selenium+phantomjs
- scrapy框架
- 基本用法
- 中間件-代理、登錄
- 抓取環(huán)
- 分布式爬蟲
- scrapy_redis,
- scrapy-cluster(加入kafka利器)
- scrapy的改造
- 自定義下載器
- 手機(jī)app數(shù)據(jù)抓取
- 利用代理抓接口(青花瓷)
- appium(selenium和appium原本都是自動化測試工具,用來做爬蟲也是很好的)
通過以上學(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了。
先到這里吧,以后再說頁面提取。