tenliu的爬虫-requests学习

通过以上学习,爬虫算是入门了,掌握urllib、urllib2我们已经具备了可以抓取网上大部分页面的能力了。
但是我们前面也已经讲了urllib和urllib2的槽点,可以用来做爬虫,但是比较不便,有点违背python的主旨了。
这里介绍 python的第三方库:requests

requests概述

requests官方slogan是这样一句话:

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

针对谁不言而喻,urllib和urllib2的槽点太多,这不必说。问题是requests是否有吐槽他们的资格呢,它到底有多便利?

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

  • Keep-Alive & 连接池
  • 国际化域名和 URL
  • 带持久 Cookie 的会话
  • 浏览器式的 SSL 认证
  • 自动内容解码
  • 基本/摘要式的身份认证
  • 优雅的 key/value Cookie
  • 自动解压
  • Unicode 响应体
  • HTTP(S) 代理支持
  • 文件分块上传
  • 流下载
  • 连接超时
  • 分块请求
  • 支持 .netrc

requests安装

requests库并非出自python基金会,一般安装python后不会自带requests,使用时需要安装:

pip install requests

requests类和方法

requests发展至今,功能上有很大扩展,类和方法也是很多。这里主要将一些爬虫常用的,希望兼顾实用和全面。

requests.Response类

requests的响应类。

属性 说明
encoding requests从响应的header自动猜测出响应页面编码方式
apparent_encoding requests从响应页面猜测响应页面编码方式
url 响应的url
status_code 响应的http状态码
cookies 响应的cookies
elapsed 发送请求到收到响应消耗的时间
headers 响应的headers
history 请求历史
headers 响应的headers
content 页面源码,str
text 也是页面源码,unicode,requests自动解码

这里需要注意的是,不少人使用requests都有乱码的困扰,就是因为上面属性content和text没搞清楚的问题,以后单独讲讲这个问题。

requests.Session类

提供cookie持久性、连接池和配置。
requests提供的一个会话类,可以使用在爬虫抓取时需要保持登录状态的情况

七个请求方法

如下六个请求方法:

  • 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对象。
有点被吓到了,那么我们仅仅使用

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

这两个即可,分别是get请求和post请求,其他的在爬虫中使用率不高。

请求参数**kwargs

参数 说明
params 自动构建url,get请求时使用
data 提交表单,post请求时使用
headers 请求headers
cookies 请求cookies
timeout 超时时间
proxies ip代理
json 发送json
file 发送文件(Multipart-Encoded)
allow_redirects
auth
verify
stream
cert

requests实例讲解

get方法-基本

这里我们看requests发送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方法,认识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请求-自动构建url请求参数

requests.get()的params参数,我们上面也说了,可以自动把params参数拼接在url中。当然你也可以手工构建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()

执行,打印页面源码,我们看到get请求参数传递成功。

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"}};

同时,这里我们注意到requests再也不用urlencode编码啦。urllib和urllib2惭不惭愧。
爬虫-urllib2学习

post方法

requests.post()中data用来post参数

#!/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()

执行打印页面源码,可以看到post方式传递参数成功:

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

以上的爬虫都是没有伪装的,看看之前例子的执行结果中:
"HTTP_USER_AGENT":"python-requests/2.18.4"

USER_AGENT是python-requests/2.18.4(我安装的是2.18.4版本),明确告诉服务器自己爬虫的身份了,被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()

执行打印源码,可以看到伪装成功。

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编码传输内容,添加ip代理抓取处理比较麻烦,不是这里要讲的内容)

我自己构建了一个ip代理池,定时验证。这里有一个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()

执行结果如下

IP查询 - 您的 IP:121.196.226.246 来自:浙江省杭州市 阿里巴巴网络有限公司

上面例子中有

from lxml import etree

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

这里涉及到页面提取的xpath语法,和python对xpath的支持包lxml,也不是这里讲的内容,下一篇会单独说说“页面解析”,这也是爬虫很重要的内容。

session

下面是session的简单例子,更详细的用法还要在实际应用中施展。

#!/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()

这个例子当然很简单,更具体的使用场景是:
在抓取需要登录信息的页面时,如果没有session,只能保存cookies,在每次抓取时都发送cookies。但是使用session,登录后可以不用考虑cookies了。

先到这里吧,以后再说页面提取。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容