【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