python requests和urllib_Python——深入理解urllib、urllib2及requests(requests不建议使用?)...

深入理解urllib、urllib2及requests

Python 是一种面向对象、解释型计算机程序设计语言,由Guido van

Rossum于1989年底发明,第一个公开发行版发行于1991年,Python 源代码同样遵循 GPL(GNU General Public

License)协议[1] 。Python语法简洁而清晰,具有丰富和强大的类库。

urllib and urllib2 区别

urllib和urllib2模块都做与请求URL相关的操作,但他们提供不同的功能。

urllib2.urlopen accepts

an instance of the Request class or a url, (whereas urllib.urlopen only

accepts a url

中文意思就是:urllib2.urlopen可以接受一个Request对象或者url,(在接受Request对象时候,并以此可以来设置一个URL

的headers),urllib.urlopen只接收一个url

urllib 有urlencode,urllib2没有,这也是为什么总是urllib,urllib2常会一起使用的原因r = Request(url='http://www.mysite.com')

r.add_header('User-Agent', 'awesome fetcher')

r.add_data(urllib.urlencode({'foo': 'bar'})

response = urllib2.urlopen(r)     #post method

urllib 模块

I. urlencode不能直接处理unicode对象,所以如果是unicode,需要先编码,有unicode转到utf8,举例:urllib.urlencode (u'bl'.encode('utf-8'))

II. 示例import urllib       #sohu 手机主页

url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_smuid=\

ICvXXapq5EfTpQTVq6Tpz'

resp = urllib.urlopen(url)

page = resp.read()

f = open('./urllib_index.html', 'w')

f.write(page)

print dir(resp)

结果:['doc', 'init', 'iter', 'module', 'repr', 'close', 'code', 'fileno', 'fp', 'getcode', 'geturl', 'headers', 'info', 'next', 'read', 'readline', 'readlines', 'url']

print resp.getcode(), resp.geturl(), resp.info(), resp.headers, resp.url

#resp.url和resp.geturl()结果一样

III. 编解码示例 urllib.quote和urllib.urlencode都是编码,但用法不一样48     s = urllib.quote('This is python')  #编码 49     print 'quote:\t'+s    #空格用%20替代 50     s_un = urllib.unquote(s)    #解码 51     print 'unquote:\t'+s_un 52     s_plus = urllib.quote_plus('This is python')  #编码 53     print 'quote_plus:\t'+s_plus            #空格用+替代 54     s_unplus = urllib.unquote_plus(s_plus)       #解码 55     print 's_unplus:\t'+s_unplus 56     s_dict = {'name': 'dkf', 'pass': '1234'} 57     s_encode = urllib.urlencode(s_dict)    #编码字典转换成url参数

58     print 's_encode:\t'+s_encode

结果:quote: This%20is%20python

unquote:   This is python

quote_plus:    This+is+python

s_unplus:  This is python

s_encode:  name=dkf&pass=1234

IV. urlretrieve() urlretrieve多数适用单纯的只下载的功能或者显示下载的进度等75     url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_\

smuid=ICvXXapq5EfTpQTVq6Tpz'

76     urllib.urlretrieve(url, './retrieve_index.html')

#直接把url链接网页内容下载到retrieve_index.html里了,适用于单纯的下载的功能。

#urllib.urlretrieve(url, local_name, method)

urllib2

I. urllib2模块定义的函数和类用来获取URL(主要是HTTP的),他提供一些复杂的接口用于处理:

基本认证,重定向,Cookies等。 II. 常用方法和类 II.1 urllib2.urlopen(url[, data][,

timeout]) #传url时候,用法同urllib里的urlopen II.1.1

它打开URL网址,url参数可以是一个字符串url或者是一个Request对象。可选的参数timeout,阻塞操作以秒为单位,如尝试连接(如果没

有指定,将使用设置的全局默认timeout值)。实际上这仅适用于HTTP,HTTPS和FTP连接。85     url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_\

smuid=ICvXXapq5EfTpQTVq6Tpz'86     resp = urllib2.urlopen(url)87     page = resp.read()

II.1.2

urlopen方法也可通过建立了一个Request对象来明确指明想要获取的url。调用urlopen函数对请求的url返回一个response对

象。这个response类似于一个file对象,所以用.read()函数可以操作这个response对象url = 'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_smuid\

=ICvXXapq5EfTpQTVq6Tpz'

req = urllib2.Request(url)

resp = urllib2.urlopen(req)

page = resp.read()

II.2 class urllib2.Request(url[, data][, headers][, originreqhost][, unverifiable])

II.2.1 Request类是一个抽象的URL请求。5个参数的说明如下: II.2.1.1

URL——是一个字符串,其中包含一个有效的URL。 II.2.1.2

data——是一个字符串,指定额外的数据发送到服务器,如果没有data需要发送可以为“None”。目前使用data的HTTP请求是唯一的。当请求

含有data参数时,HTTP的请求为POST,而不是GET。数据应该是缓存在一个标准的application/x-www-form-

urlencoded格式中。urllib.urlencode()函数用映射或2元组,返回一个这种格式的字符串。通俗的说就是如果想向一个URL发送

数据(通常这些数据是代表一些CGI脚本或者其他的web应用)。例如在网上填的form(表单)时,浏览器会POST表单的内容,这些数据需要被以标准

的格式编码(encode),然后作为一个数据参数传送给Request对象。Encoding是在urlib模块中完成的,而不是在urlib2中完成

的。下面是个例子:import urllib

import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'values = {'name' : 'Michael Foord',       'location' : 'Northampton',       'language' : 'Python' }

data = urllib.urlencode(values)

req = urllib2.Request(url, data)   #send post

response = urllib2.urlopen(req)

page = response.read()

II.2.1.3

headers——是字典类型,头字典可以作为参数在request时直接传入,也可以把每个键和值作为参数调用add_header()方法来添加。作

为辨别浏览器身份的User-Agent

header是经常被用来恶搞和伪装的,因为一些HTTP服务只允许某些请求来自常见的浏览器而不是脚本,或是针对不同的浏览器返回不同的版本。例

如,Mozilla Firefox浏览器被识别为“Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127

Firefox/2.0.0.11”。默认情况下,urlib2把自己识别为Python-urllib/x.y(这里的xy是python发行版的主要

或次要的版本号,如在Python

2.6中,urllib2的默认用户代理字符串是“Python-urllib/2.6。下面的例子和上面的区别就是在请求时加了一个headers,模

仿IE浏览器提交请求。import urllib

import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'values = {'name' : 'Michael Foord',        'location' : 'Northampton',        'language' : 'Python' }

headers = { 'User-Agent' : user_agent }

data = urllib.urlencode(values)

req = urllib2.Request(url, data, headers)

response = urllib2.urlopen(req)

the_page = response.read()

标准的headers组成是(Content-Length, Content-Type and

Host),只有在Request对象调用urlopen()(上面的例子也属于这个情况)或者OpenerDirector.open()时加入。两种

情况的例子如下:

使用headers参数构造Request对象,如上例在生成Request对象时已经初始化header,而下例是Request对象调用

add_header(key, val)方法附加header(Request对象的方法下面再介绍):import urllib2

req = urllib2.Request('http://www.example.com/')

req.add_header('Referer', 'http://www.python.org/')

#http是无状态的协议,上一次客户端的请求与下一次客户端到服务器的请求无关系的,多数省略这一步

r = urllib2.urlopen(req)

OpenerDirector为每一个Request自动加上一个User-Agent header,所以第二种方法如下(urllib2.buildopener会返回一个OpenerDirector对象,关于urllib2.buildopener类下面再说):import urllib2

opener = urllib2.build_opener()

opener.addheaders = [('User-agent', 'Mozilla/5.0')]

opener.open('http://www.example.com/')

II.3 urllib2.installopener(opener)和urllib2.buildopener([handler, ...])

installopener和buildopener这两个方法通常都是在一起用,也有时候buildopener单独使用来得到OpenerDirector对象。

installopener

实例化会得到OpenerDirector

对象用来赋予全局变量opener。如果想用这个opener来调用urlopen,那么就必须实例化得到OpenerDirector;这样就可以简单

的调用OpenerDirector.open()来代替urlopen()。

build_opener实例化也会得到

OpenerDirector对象,其中参数handlers可以被BaseHandler或他的子类实例化。子类中可以通过以下实例

化:ProxyHandler (如果检测代理设置用)扫描代理会用到,很重要这个, UnknownHandler, HTTPHandler,

HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler,

HTTPErrorProcessor。import urllib2

req = urllib2.Request('http://www.python.org/')

opener=urllib2.build_opener()

urllib2.install_opener(opener)

f = opener.open(req)

如上使用 urllib2.install_opener()设置 urllib2 的全局

opener。这样后面的使用会很方便,但不能做更细粒度的控制,比如想在程序中使用两个不同的 Proxy 设置等。比较好的做法是不使用

install_opener 去更改全局的设置,而只是直接调用 opener的open 方法代替全局的 urlopen 方法。

说到这Opener和Handler之间的操作听起来有点晕。整理下思路就清楚了。当获取一个URL时,可以使用一

个opener(一个urllib2.OpenerDirector实例对象,可以由build_opener实例化生成)。正常情况下程

序一直通过urlopen使用默认的opener(也就是说当你使用urlopen方法时,是在隐式的使用默认的opener

对象),但也可以创建自定义的openers(通过操作 器handlers创建的opener实例)。所有的重活和麻烦

都交给这些handlers来做。每一个handler知道如何以一种特定的协议(http,ftp等等)打开url,或

者如何处理打开url发生的HTTP重定向,或者包含的HTTP cookie。创建openers时如果想要安装特别的han

dlers来实现获取url(如获取一个处理cookie的opener,或者一个不处理重定向的opener)的话,先实例

一个OpenerDirector对象,然后多次调用.add_handler(some_handler_instance)来创建一个opene

r。或者,你可以用build_opener,这是一个很方便的创建opener对象的函数,它只有一个函数调用

。build_opener默认会加入许多handlers,它提供了一个快速的方法添加更多东西和使默认的handler 失效。

install_opener如上所述也能用于创建一个opener对象,但是这个对象是(全局)默认的opener。这意味着调用urlopen

将会用到你刚创建的opener。也就是说上面的代码可以等同于下面这段。这段代码最终还是使用的默认opener。一般情况下我们用

build_opener为的是生成自定义opener,没有必要调用install_opener,除非是为了方便。import urllib2

req = urllib2.Request('http://www.python.org/')

opener=urllib2.build_opener()       # 创建opener对象

urllib2.install_opener(opener)      #定义全局默认opener

f = urllib2.urlopen(req)          #urlopen使用默认opener,但是install_opener

#已经把opener设为全局默认了,这里便是使用上面的建立的opener

III. 异常处理http://www.jb51.net/article/63711.htm当我们调用urllib2.urlopen的时候不会总是这么顺利,就像浏览器打开url时有时也会报 错,所以就需要我们有应对异常的处理。说到异常,我们先来了解返回的response对象的 几个常用的方法:

geturl() — 返回检索的URL资源,这个是返回的真正url,通常是用来鉴定是否重定向的

info() — 返回页面的原信息就像一个字段的对象, 如headers,它以mimetools.Message实例为格式(可以参考HTTP Headers说明)。

getcode()

— 返回响应的HTTP状态代码,运行下面代码可以得到code=200

当不能处理一个response时,urlopen抛出一个URLError(对于python APIs,内建异常如,ValueError,

TypeError 等也会被抛出。)HTTPError是HTTP

URL在特别的情况下被抛出的URLError的一个子类。下面就详细说说URLError和HTTPError。

URLError——handlers当运行出现问题时(通常是因为没有网络连接也就是没有路由到指定的服务器,或在指定的服务器不存在)

HTTPError——HTTPError是URLError的子类。每个来自服务器HTTP的response都包含“status

code”. 有时status code不能处理这个request.

默认的处理程序将处理这些异常的responses。例如,urllib2发现response的URL与你请求的URL不同时也就是发生了重定向时,会

自动处理。对于不能处理的请求, urlopen将抛出 - - - HTTPError异常. 典型的错误包含‘404’ (没有找到页面),

‘403’ (禁止请求),‘401’ (需要验证)等。它包含2个重要的属性reason和code。

程序对于重定向时默认处理的

总结

如果只是单纯的下载或者显示下载进度,不对下载后的内容做处理等,比如下载图片,css,js文件等,可以用urlilb.urlretrieve()

如果是下载的请求需要填写表单,输入账号,密码等,建议用urllib2.urlopen(urllib2.Request())

在对字典数据编码时候,用到的是urllib.urlencode()

requests

I. Requests 使用的是

urllib3,继承了urllib2的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自

动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。 II. 举例:import requests

...

resp = requests.get('http://www.mywebsite.com/user')

userdata = {"firstname": "John", "lastname": "Doe", "password": "jdoe123"}

resp = requests.post('http://www.mywebsite.com/user', params=userdata)

resp = requests.put('http://www.mywebsite.com/user/put')

resp = requests.delete('http://www.mywebsite.com/user/delete')

resp.json()   # 假如返回的是json数据

resp.text     #返回的不是text数据

resp.headers['content-type']  #返回text/html;charset=utf-8

f = open('request_index.html', 'w')

f.write(page.encode('utf8'))

#test 发现requests抓下来的页面必须要编码\

#写入,(抓下来的是unicode),urllib和urllib2抓下来可以直接写入,

#因为这两者抓下来的page是str

III. 其他功能特性国际化域名和 URLs

Keep-Alive & 连接池

持久的 Cookie 会话

类浏览器式的 SSL 加密认证

基本/摘要式的身份认证

优雅的键/值 Cookies

自动解压

Unicode 编码的响应体

多段文件上传

连接超时

支持 .netrc

适用于 Python 2.6—3.4线程安全

IV. requests不是python自带的库,需要另外安装 easy_install or pip install

V. requests缺陷:直接使用不能异步调用,速度慢(from others)。官方的urllib可以替代它。

VI. 个人不建议使用requests模块

更详细的相关介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssh查找linux端口,linux – 查找当前连接的端口号SSH

我正在使用SSH连接创建一个本地模拟器(未连接到Internet).我已经开始使用特定范围的端口号进行sshd,并对一系列设备进行NAT处理.我必须找到当前连接的端口号.OS CentOS 5.5OpenSSH 6.1我做了以下事情.它适用于正常使用(手动用户).但是当尝试严格的测试(自动化)时,似乎有时找不到…

this.getstate_Java线程类Thread.State getState()方法(带示例)

this.getstate线程类Thread.State getState() (Thread Class Thread.State getState()) This method is available in package java.lang.Thread.getState(). 软件包java.lang.Thread.getState()中提供了此方法。 This method is used to return the state of this thread. 此方…

Java资源大全中文版(Awesome最新版)

来源:http://www.cnblogs.com/best/p/5876559.html 目录 业务流程管理套件字节码操作集群管理代码分析编译器生成工具构建工具外部配置工具约束满足问题求解程序持续集成CSV解析数据库数据结构时间日期工具库依赖注入开发流程增强工具分布式应用分布式数据库发布文档…

运用多种设计模式的综合案例_SpreadJS 纯前端表格控件应用案例:表格数据管理平台...

由某科技公司研发的表格数据管理平台,是一款面向业务和企业管理系统定制开发的应用平台,包括类 Excel 设计器、PC应用端和移动应用端等应用模块。该平台具备强大的业务配置和集成开发能力,对于企业客户的信息系统在管理模式、业务流程、表单界…

linux定位哪个进程出发重启,定位Linux下定位进程被谁KILL

hezhaoaqiang2012-11-09 11:10可以请教你一个问题吗?关于arm的交叉编译。我是按照:http://blog.chinaunix.net/uid-27003388-id-3276139.html 去做的,但是走到 四、建立初始编译器(bootstrap gcc)下面的make install 它提示如下:m…

Java Integer类numberOfLeadingZeros()方法的示例

整数类numberOfLeadingZeros()方法 (Integer class numberOfLeadingZeros() method) numberOfLeadingZeros() method is available in java.lang package. 在java.lang包中提供了numberOfLeadingZeros()方法 。 numberOfLeadingZeros() method is used to returns the number o…

VS中C++ 项目重命名

应该都有过这样的经历,在Visual studio中创建解决方案,添加几个项目进去,然后开始愉快的敲代码...。写代码正欢的时候,却总是感觉那里有些不舒服,一细看,这项目名称取的真心挫,修改个吧。直接右…

Java GregorianCalendar getActualMinimum()方法与示例

GregorianCalendar类getActualMinimum()方法 (GregorianCalendar Class getActualMinimum() method) getActualMinimum() method is available in java.util package. getActualMinimum()方法在java.util包中可用。 getActualMinimum() method is used to get the actual minim…

axure9数据统计插件_WMDA:大数据技术栈的综合实践

一、概述WMDA是58自主开发的用户行为分析产品,同时也是一款支持无埋点的数据采集产品,只需要在第一次使用的时候加载一段SDK代码,即可采集全量、实时的PC、M、APP三端以及小程序的用户行为数据。同时,为了满足用户个性化的数据采集…

Java Collections unmodifiableCollection()方法与示例

集合类unmodifiableCollection()方法 (Collections Class unmodifiableCollection() method) unmodifiableCollection() method is available in java.util package. unmodifiableCollection()方法在java.util包中可用。 unmodifiableCollection() method is used to get an un…

openfoam安装中出现allmake error_如何更新OpenFOAM的版本?

这是协作翻译的第四章,翻译完感觉挺有意思的,分享给大家一起看看。4.更新OpenFOAM版本4.1 版本管理OpenFOAM以两种不同的方式分发。一种方式是使用Git仓库下载的仓库版本。仓库版本的版本号由附加的x标记,例如 OpenFOAM2.1.x。该版本会经常更…

java 根据类名示例化类_Java类类的requiredAssertionStatus()方法和示例

java 根据类名示例化类类的类requiredAssertionStatus()方法 (Class class desiredAssertionStatus() method) desiredAssertionStatus() method is available in java.lang package. requiredAssertionStatus()方法在java.lang包中可用。 desiredAssertionStatus() method is …

python中计算排列组合的函数_Python实现的排列组合计算操作示例

本文实例讲述了Python实现的排列组合计算操作。分享给大家供大家参考,具体如下:1. 调用 scipy 计算排列组合的具体数值>> from scipy.special import comb, perm>> perm(3, 2)6.0>> comb(3, 2)3.02. 调用 itertools 获取排列组合的全部…

java日历类add方法_Java日历setMinimalDaysInFirstWeek()方法与示例

java日历类add方法日历类setMinimalDaysInFirstWeek()方法 (Calendar Class setMinimalDaysInFirstWeek() method) setMinimalDaysInFirstWeek() method is available in java.util package. setMinimalDaysInFirstWeek()方法在java.util包中可用。 setMinimalDaysInFirstWeek(…

相同布局在不同手机上显示不同_不懂响应式,不同尺寸屏幕下的页面很难达到最佳效果...

让用户在不同设备和尺寸的屏幕下看的页面显示效果更佳,屏幕空间利用更高,操作体验更统一,交互方式更符合习惯。本文主要围绕什么是响应式,如何搭建响应系统,响应式网站解析 三个部分进行阐述,在项目中提前定…

Java ByteArrayInputStream markSupported()方法与示例

ByteArrayInputStream类markSupported()方法 (ByteArrayInputStream Class markSupported() method) markSupported() method is available in java.util package. markSupported()方法在java.util包中可用。 markSupported() method is used to check whether this ByteArrayI…

markdown 流程图_测试了12款Markdown编辑器,推荐一个最好用的!

有很多喜欢写博客的小伙伴问我,这个代码笔记的格式怎么弄的简洁又好看,虽然csdn里面有Markdown的书写模式,但是我还是想推荐一款比较好用的写笔记的编辑器 - Typora。相信很多小伙伴都在使用吧,这个一直是我最喜欢的 markdown 编辑…

小程序 || 语句_C ++条件语句| 查找输出程序| 套装2

小程序 || 语句Program 1: 程序1&#xff1a; #include <iostream>#include <stdio.h>using namespace std;int main(){int num 0;num printf("%d ", printf("%d ", printf("ABC")));if (num 2) {cout << "INDIA&quo…

python爬取天气预报源代码_python抓取天气并分析 实例源码

【实例简介】Python代码抓取获取天气预报信息源码讲解。这是一个用Python编写抓取天气预报的代码示例&#xff0c;用python写天气查询软件程序很简单。这段代码可以获取当地的天气和、任意城市的天气预报&#xff0c;原理是根据url找到网站截取相应的数据展现。python抓取广州天…

Linux编译程序源码环境,Linux下对nodejs环境进行源码编译并部署云应用

Node 是一个让 JavaScript 运行在服务端的开发平台&#xff0c;它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。该环境安装非常简单&#xff0c;这里简单记录下linux(centos环境下)的源码安装&#xff0c;做个记录。平台&#xff1a;centos 6…