pythonurllib - juedaiyuer/researchNote GitHub Wiki
#urllib#
##扒网页##
扒下一个网页
import urllib2
response = urllib2.urlopen("http://www.baidu.com")
print response.read()
urlopen的参数
urlopen(url,data,timeout)
data,timeout可以不传送
data默认为空None
timeout默认为socket._GLOBAL_DEFAULT_TIMEOUT
response对象有一个read方法,可以返回获取到的网页内容
直接打印response,打印出了该对象的描述
>>> print response
<addinfourl at 140230693113584 whose fp = <socket._fileobject object at 0x7f8a0334bbd0>>
##构造Request##
urlopen参数可以传入一个request请求,它其实就是一个Request类的实例,构造时需要传入url,data等内容;构建请求时需要加入好多内容,通过构建一个request,服务器响应请求得到应答
import urllib2
request = urllib2.Request("http://www.baidu.com")
response = urllib2.urlopen(request)
print response.read()
##POST和GET数据传送##
动态网页,需要动态地传递参数给它,做出对应的响应,最常见的情况是登录注册
把数据用户名和密码传送到一个URL,得到服务器处理之后的响应
数据传送分为POST和GET两种方式:
- GET方式是直接以链接形式访问,链接中包含了所有的参数,如果包含了密码的话是一种不安全的选择,但是可以直接看到自己提交了什么内容
- POST则不会在网址上显示所有的参数
###POST方式###
登录CSDN的例子
import urllib
import urllib2
values = {"username":"[email protected]","password":"XXXX"}
data = urllib.urlencode(values)
url = "https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn"
request = urllib2.Request(url,data)
response = urllib2.urlopen(request)
print response.read()
下面的代码等价于上面的代码
import urllib
import urllib2
values={}
values['username'] = "[email protected]"
values['password']="XXXX"
data = urllib.urlencode(values)
url = "http://passport.csdn.net/account/login"
geturl = url + "?"+data
request = urllib2.Request(geturl)
response = urllib2.urlopen(request)
print response.read()
##设置Headers##
有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,为了完全模拟浏览器的工作,需要设置一些Headers的属性
agent就是请求的身份,如果没有写入请求身份,服务器不一定会响应。下面的例子只是说明了怎样设置headers,看一下它的设置格式
import urllib
import urllib2
url = 'http://www.server.com/login'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'username' : 'cqc', 'password' : 'XXXX' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
page = response.read()
对付防盗链,服务器会识别headers中的referer是不是它自己,如果不是,有的服务器不会响应
headers = { 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)','Referer':'http://www.zhihu.com/articles' }
##headers的一些属性##
User-Agent : 有些服务器或Proxy会通过该值来判断是否是浏览器发出的请求
Content-Type : 在使用 REST 接口时,服务器会检查该值,用来确定 HTTP Body 中的内容该怎样解析
application/xml : 在XML RPC,如RESTful/SOAP调用时使用
application/json : 在 SON RPC调用时使用
application/x-www-form-urlencoded : 浏览器提交Web表单时使用
在使用服务器提供的 RESTful 或 SOAP 服务时, Content-Type设置错误会导致服务器拒绝服务
##Proxy(代理)的设置##
urllib2默认会使用环境变量http_proxy来设置HTTP Proxy
假如一个网站它会检测某一段时间某个IP 的访问次数,如果访问次数过多,它会禁止你的访问
所以你可以设置一些代理服务器来帮助你做工作,每隔一段时间换一个代理
import urllib2
enable_proxy = True
proxy_handler = urllib2.ProxyHandler({"http" : 'http://some-proxy.com:8080'})
null_proxy_handler = urllib2.ProxyHandler({})
if enable_proxy:
opener = urllib2.build_opener(proxy_handler)
else:
opener = urllib2.build_opener(null_proxy_handler)
urllib2.install_opener(opener)
##使用HTTP的PUT和DELETE方法##
http协议有六种请求方法,get,head,put,delete,post,options
PUT:这个方法比较少见。HTML表单也不支持这个。本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
DELETE:删除某一个资源。基本上这个也很少见,不过还是有一些地方比如amazon的S3云服务里面就用的这个方法来删除资源
##URLError##
存在的原因:
- 网络无连接,即本机无法上网
- 连接不到特定的服务器
- 服务器不存在
在代码中,我们需要用try-except语句来包围并捕获相应的异常
import urllib2
requset = urllib2.Request('http://www.xxxxx.com')
try:
urllib2.urlopen(requset)
except urllib2.URLError, e:
print e.reason
##HTTPError##
HTTPError是URLError的子类,在你利用urlopen方法发出一个请求时,服务器上都会对应一个应答对象response,其中它包含一个数字”状态码”
其他不能处理的,urlopen会产生一个HTTPError,对应相应的状态吗,HTTP状态码表示HTTP协议所返回的响应的状态。
HTTPError实例产生后会有一个code属性,这就是是服务器发送的相关错误号
因为urllib2可以为你处理重定向,也就是3开头的代号可以被处理,并且100-299范围的号码指示成功,所以你只能看到400-599的错误号码
import urllib2
req = urllib2.Request('http://blog.csdn.net/cqcre')
try:
urllib2.urlopen(req)
except urllib2.HTTPError, e:
print e.code
print e.reason
运行结果
403
Forbidden
HTTPError的父类是URLError,根据编程经验,父类的异常应当写到子类异常的后面,如果子类捕获不到,那么可以捕获父类的异常,所以上述的代码可以这么改写
import urllib2
req = urllib2.Request('http://blog.csdn.net/cqcre')
try:
urllib2.urlopen(req)
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.reason
else:
print "OK"
另外还可以加入 hasattr属性提前对属性进行判断,代码改写如下
import urllib2
req = urllib2.Request('http://blog.csdn.net/cqcre')
try:
urllib2.urlopen(req)
except urllib2.URLError, e:
if hasattr(e,"code"):
print e.code
if hasattr(e,"reason"):
print e.reason
else:
print "OK"
##source##