【6】网络与网页-1-API的交互--Requests

Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。

一、Requests的安装

官网:https://pypi.python.org/pypi/requests/

中文资料:http://cn.python-requests.org/zh_CN/latest/

pip install requests

#coding:UTF-8
 import requests
 r = requests.get(r'http://www.baidu.com')
 print r.status_code
 #状态位200,表示访问成功
r.encoding ='utf-8'
 print r.text
 #输出网页内容

二、Requests的常用的几个方法

1.get方法

r = requests.get(r'http://www.baidu.com')

构造一个向服务器请求资源的Request对象,返回一个包含服务器资源的Response对象(用r来表示)

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

Response对象的属性

r.status_code http请求的返回状态,200代表连接成功,404代表失败
 r.text http响应内容的字符串形式,即url对应的页面内容
 r.encoding 从http header中猜测出来的相应内容编码方式(如果header中不存在charset,
 则编码默认为ISO-8859-1,这样的编码并不能解析中文)
 r.apparent_encoding 从内容中分析出的响应内容的编码方式(备选编码方式,比encoding得到的
 编码方式更准确)
 r.content http响应内容的二进制形式(如:图片)

先根据r.status_code判断访问是否成功:

如果是200,再来看r.text,r.encoding,r.apparent_encoding,r.content

如果是404,则报错

#coding:UTF-8
 import requests
 r = requests.get(r'http://www.baidu.com')
 print r.status_code
 #状态位200,表示访问成功
#r.encoding ='utf-8'
 print r.text
 #看到一堆乱码
print r.encoding
 #ISO-8859-1

print r.apparent_encoding
 #utf-8

r.encoding = 'utf-8'
 print r.text
 #替换encoding方式后,看到就不是乱码了

2.通用代码框架

requests库的异常

requests.ConnectionError 网络连接错误异常,如DNS查询失败,拒绝连接等
 requests.HTTPError HTTP错误异常
 requests.URLRequired URL缺失异常
 requests.TooManyRedirects 超过最大重定向次数,产生重定向异常
 requests.ConnectTimeout 连接远程服务器超时异常
 requests.Timeout 请求URL超时,产生超时异常

r.raise_for_status() 如果不是200,产生异常requests.HTTPError

通用代码框架

#coding:UTF-8
import requests

def getHTMLText(url):
 try:
	 r = requests.get(url,timeout = 30)
	 r.raise_for_status()  #状态如果不是200,则报错哦
	 r.encoding = r.apparent_encoding
	 return r.text
 except :
	 return '产生异常'

if __name__ == '__main__':
 url = 'http://www.baidu.com'
 print getHTMLText(url)

3.http协议和requests的主要方法

requests的主要方法:

requests.request() 构造一个请求,支撑以下各方法的基础方法
 requests.get() 获取HTML网页的主要方法,对应于HTTP的GET
 requests.head() 获取HTML网页头信息的主要方法,对应于HTTP的HEAD
 requests.post() 向HTML网页提交POST请求的主要方法,对应于HTTP的POST
 requests.put() 向HTML网页提交PUT请求的主要方法,对应于HTTP的PUT
 requests.patch() 向HTML网页提交局部修改请求,对应于HTTP的PATCH
 requests.delete() 向HTML网页提交删除请求,对应于HTTP的DELETE

HTTP协议:

1.HTTP,HyperText Transfer Protocol,超文本传输协议

2.HTTP是一个基于‘请求与相应’模式的,无状态的应用层协议(无状态指第一次请求和第二次请求 并没有关联,应用层协议指TCP协议之上)

3.HTTP协议采用URL定位网络资源的标识

URL格式 http://host[:port][path]
host:合法的Internet主机域名或IP地址
port:端口号,缺省端口为80
path:请求资源的地址

URL是通过HTTP协议存取资源的Internet路径,一个URL对应一个数据资源

HTTP协议对资源的操作

  • GET 请求获取URL位置的资源
  • HEAD 请求获取URL位置资源的相应消息报告,即获得该资源的头部信息
  • POST 请求向URL位置的资源后附加新的数据
  • PUT 请求向URL位置存储一个资源,覆盖原URL位置的资源
  • PATCH 请求局部更新URL位置的资源,即改变该处资源的部分内容(比put更能节省网页带宽)
  • DELETE 请求删除URL位置存储的资源

4.requests的主要解析

requests.request(method,url,*kwargs)
method: 请求方式,对应GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS等七种
url:获取访问网页地址

**kwargs : 控制访问的参数,均为可选项,包括13个可选参数:

params: 字典或字节序列,作为参数增加到url中

url = 'http://www.baidu.com'
 kv = {'key1': 'value1','key2':'value2'}
 r = requests.request('GET',url,params=kv)
 print r.url
 #http://www.baidu.com/?key2=value2&key1=value1

data:字典,字节序列或文件对象,作为Requests的内容

url = 'http://www.baidu.com'
 kv = {'key1': 'value1','key2':'value2'}
 r = requests.request('POST',url,data=kv)
 print r.url
 #http://www.baidu.com/

json:json格式的数据,作为Requests的内容

url = 'http://www.baidu.com'
 kv = {'key1': 'value1','key2':'value2'}
 r = requests.request('POST',url,json=kv)

headers: 字典,HTTP定制头

kv = {'user-agent': 'Chrome/10'}
 r = requests.request('POST',url,headers=kv)

cookies :字典或CookieJar,Request中的cookie
auth : 元祖,支持HTTP认证
files: 字典类型,传输文件
url = 'http://www.baidu.com'
fs = {'file': open('data.xls','rb')}
r = requests.request('POST',url,files=fs)
timeout:设定超时时间,秒为单位
proxies: 字典类型,设定访问代理服务器,可以增加登陆认证
url = 'http://www.baidu.com'
pxs = {'http': 'http://user:pass@10.10.10.10.1:1234',
'https': 'http://10.10.10.10.1:3334'
}
r = requests.request('POST',url,proxies=pxs)
我们访问百度的时候,就是用的代理服务器的IP地址,可以有效隐藏用户爬虫的时候,源的IP地址信息
all_redirects: True/False,默认为True,重定向开关
stream: True/False,默认为True,获取类容立即下载开关
verify: True/False,默认为True,认证SSL证书开关
cert:本地SSL证书路径
requests.get(url,params=None,**kwargs)
requests.head(url,**kwargs)
requests.post(url,data=None,json=None,**kwargs)
requests.put(url,data=None,**kwargs)
requests.patch(url,data=None,**kwargs)
requests.delete(url,**kwargs)
**kwargs为以上可选的13个参数

三、网络爬虫带来的问题

网络爬虫的尺寸

1.小规模,数据量小,爬取速度不敏感

Requests库

爬取网页,玩转网页

2.中规模,数据量较大,爬取速度敏感

Scrapy库

爬取网站,爬取系列网站

3.大规模,搜索引擎,爬取速速关键

定制开发

爬取全网

骚扰问题:受限于编写水平和目的,网页爬虫将会为web服务器带来巨大的资源开销

法律风险:服务器上的数据有产权归属,网络爬虫获取的数据谋取利润将带来法律风险

隐私泄露带来隐私泄露的风险

网页爬虫的限制

来源审查:判断User-Agent进行限制

检查来访HTTP协议头的User-Agent域,只响应浏览器或友好爬虫的访问

发布公告:Robots协议

告知所有爬虫网站的爬取策略,要求爬虫遵守

四、Robots协议

Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),

作用:告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

形式:在网站根目录的robots.txt文件

基本语法:

User-agent:* #表明哪些爬虫
Disallow :/ #不容许爬虫的目录

robots协议的使用

网络爬虫:自动或人工识别robots.txt,再进行内容爬取

约束性:Robots协议是建议非约束性,网络爬虫可以不遵守,但存在法律风险

五、爬虫实战

1.获得信息

2.网页查询(如:百度)

#coding:UTF-8
import requests

def getHTMLText(url):
	try:
		kv = {'user-agent' : 'Mozilla/5.0'}
		kv2= {'wd':'python'}
		r = requests.get(url,timeout = 30,headers =kv,params=kv2)
		r.raise_for_status()  #状态如果不是200,则报错哦
		r.encoding = r.apparent_encoding
		print r.url
		print r.status_code
		return len(r.text)
	except :
		return '产生异常'    

if __name__ == '__main__':
	url = 'http://www.baidu.com/s'  #为什么不是https呢??
	print getHTMLText(url)

3.图片下载和存储

#coding:UTF-8
import requests

def getHTMLText(url):
	try:
		kv = {'user-agent' : 'Mozilla/5.0'}
		kv2= {'wd':'python'}
		r = requests.get(url,timeout = 30,headers =kv,params=kv2)
		r.raise_for_status()  #状态如果不是200,则报错哦
		r.encoding = r.apparent_encoding
		print r.url
		print r.status_code
		return r
	except :
		return '产生异常'
	
def download_pic(r,pic_name):
	with open(pic_name,'wb') as f:
		f.write(r.content)	

if __name__ == '__main__':
	url = 'http://pic3.nipic.com/20090508/2305906_155034003_2.jpg'
	pic_name = '/Users/tanqianshan/Documents/project/project/requests/test.png'
	r = getHTMLText(url)

	download_pic(r,pic_name)

4.ip地址归属自动查询

#coding:UTF-8

import requests

url = 'http://www.ip138.com/ips138.asp?ip='
try:
	r = requests.get(url+'202.204.80.112')
	r.raise_for_status()  #状态如果不是200,则报错哦
	r.encoding = r.apparent_encoding

	print r.text[-500:]
except :
	print '产生异常'

六、初步认知

>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
>>> r.json()
{u'disk_usage': 368627, u'private_gists': 484, ...}

七、下载图片

def downloadImageFile(imgUrl):  
	local_filename = imgUrl.split('/')[-1]  
	print "Download Image File=", local_filename  
	r = requests.get(imgUrl, stream=True) # here we need to set stream = True parameter  
	with open("/home/pandy/"+local_filename, 'wb') as f:  
		for chunk in r.iter_content(chunk_size=1024):  
			if chunk: # filter out keep-alive new chunks  
				f.write(chunk)  
				f.flush()  
		f.close()  
	return local_filename 

案例:

def download_pic()
   img_file = requests.post(download_api, stream=True)
   with open(img_name2, "wb") as data1:
   for chunk in img_file.iter_content():
	   data1.write(chunk)

参考资料:

http://panyongzheng.iteye.com/blog/1950119

北京理工大学,嵩天老师的课件

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn