在通过pyes获取指定的doctype时不能通过mapping的get_doctype,只能通过get_doctypes获取index下的所有type,然后在自行过滤

1
2
3
4
_mapping = self._connection.indices.get_mapping(indices=index)
# _mapping.get_doctype has bug
_doctypes = _mapping.get_doctypes(index)
return doctype in dict(_doctypes)

简介

HTTP(HyperText Transfer Protocol, 超文本传输协议) 是访问互联网使用的核心通信协议,也是所有web应用程序使用的通信协议。
消息模型:客户端发送请求消息,服务器返回响应消息。传输层使用具有状态的TCP协议,但HTTP协议本身不具有状态。

HTTP请求

HTTP请求消息分为消息头和消息主体(可选),消息头和消息主体用空白行分隔。实例:

1
2
3
4
5
6
7
8
9
GET / HTTP/1.1
Host: www.cnbeta.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=cnbeta&rn=&rsv_pq=917ee072000177b3&rsv_t=67c29bDcYXbklwxp5LMXvSvgQrSWnKznmk4XgHbAghkt7XqGt%2BfEuP%2BMDo4
Cookie: Hm_lvt_4216c57ef1855492a9281acd553f8a6e=1437836998; Hm_lpvt_4216c57ef1855492a9281acd553f8a6e=1437836998; _ga=GA1.2.1311393193.1437836981; bfd_s=208385984.21594488.1437837000279; tma=208385984.15187292.1437837000282.1437837000282.1437837000282.1; tmd=1.208385984.15187292.1437837000282.; bfd_g=b56c782bcb75035d00000a500201ba8455b3a6ca
Connection: keep-alive

说明:
1.消息头第一行由三个以空格分隔的元素组成,分别为HTTP方法、请求的URL和使用的HTTP版本

  • HTTP方法;
    1). GET:用于获取资源,参数通过URL查下字符串方式提交给服务器,无消息主体
    2). POST:用于执行操作,参数可以通过URL查下字符串方式和消息主体提交给服务
    3). HEAD:用于检测资源是否存在,与GET类似,区别在于在响应消息中返回的消息主体为空
    4). TRACE:用于诊断,可判断客户端和服务器之间是否存在代理服务器,原理:服务器在响应主体中返回收到的请求消息的具体内容
    5). OPTIONS:用于要求服务器报告对某一资源有效的HTTP方法,服务器常返回Allow消息头的响应,并列出所有有效的方法
    6). PUT:使用请求主体中的内容向服务器上传指定的资源
    7). DELETE:用于删除资源
    8). CONNECT:

  • 请求URL:用于指定请求的资源名称以及查下参数

  • 使用的HTTP版本:常用1.0和1.1版本,在1.1版本中请求消息中必须包含Host请求头

2.其他

  • Host:指定请求访问的主机名,当多个web站点部署在同一台主机上时需要使用Host消息头
  • User-Agent:指定客户端软件的信息,不如浏览器类型和版本、操作系统类型和版本等
  • Referer:表示发出请求的原始URL
  • Cookie:提交服务器想客户端发布的其他参数

HTTP 响应

HTTP响应消息分为消息头和消息主体(可选),消息头和消息主体用空白行分隔。实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
HTTP/1.0 200 OK
Content-Type: text/html
Last-Modified: Sat, 25 Jul 2015 15:52:02 GMT
Vary: Accept-Encoding
Server: nginx/1.4.1
Date: Sat, 25 Jul 2015 15:53:04 GMT
ETag: "55b3b0a2-2539c"
Age: 74
X-Cache: HIT from RJ-ZSBGP-CDN-74
Set-Cookie: uuid=AQAAAEx080zNuwoAJH3PdhcuX+oK943s; Path=/; Expires=Sat, 25-Jul-15 17:09:08 GMT; HttpOnly

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>cnBeta.COM™</title>

<body>
Hello, Silence!
</body>
</html>

说明:

1.消息头第一行由三个空格分开的元素组成,分别表示HTTP版本、请求状态码(数字)、请求状态描述
2.其他:

  • Server:旗标,指明使用的Web服务器软件
  • Set-Cookie:设置cookie信息,在随后向服务器发送的请求中由Cookie消息头返回
  • Content-Type:指定消息主体类型
  • Content-Length:指定消息主体的字节长度

URL

URL(Uniform Resource Locator,统一资源定位符)是web资源的唯一标识,格式:

protocol://hostname[:port]/[path/]file[?param=value]

REST

REST(表达性状态转移)是分布式系统的一个体系架构,REST风格URL 指在URL中使用文件路径方式替代查询字符串

HTTP消息头

1.常用消息头

  • Connection:用于指定告诉通信另一端传输完成后关闭TCP连接还是保持连接,HTTP/1.1中默认为keep-alive,可设置为close
  • Content-Encoding:用于指定消息主体中编码格式
  • Content-Length;用于指定消息主体的字节长度
  • Content-Type:用于指定消息主体的内容类型
  • Transfer-Encoding:常指定为Transfer-Encoding:chunked,用于表示边产生数据边传输,在最后一块数据中0\r\n\r\n标识数据结束,在其他块数据中格式为\r\ncontent\r\n

2.请求消息头

  • Accept:用于告知服务器客户端接受哪些类型的数据
  • Accept-Encoding:用于告知服务器客户端接受哪些编码格式
  • Authorization:用于内置HTTP身份验证,用于提交用户名/密码给服务器
  • Cookie:提交Cookie
  • If-Modified-Since:用于告知服务器最后一次收到请求资源的响应时间,当资源未发生变化时服务器返回状态码304表示使用本地缓存
  • If-None-Match:用于指定实体标签,说明主体内容的标识符,当最后一次收到所请求的资源时,浏览器提交服务器发布的实体标签。服务器可通过使用实体标签确定浏览器是否使用缓存副本
  • Origin:用在Ajax跨域请求,指定发出请求的域名
  • Referer:指定发出请求额原始URL
  • User-Agent:用于指定客户端信息

3.响应消息头

  • Access-Control-Allow-Origin:用于指顶是否可通过跨域Ajax请求获取资源
  • Cache-Control:用于向浏览器发送缓存指令(no-cache)
  • Etag:指定实体标签,客户端可在后续提交实体标签获得与If-None-Match消息头相同的资源,通知服务器浏览器当前缓存保存的是哪个版本的资源
  • Expires:指定消息主体的有效时间,在时间内,浏览器可使用资源的缓存副本
  • Location:重定向响应,说用重定向的目标
  • Pragma:向浏览器传送缓存指令(no-cache)
  • Server:告知浏览器服务器软件相关信息
  • Set-Cookie:向浏览器发布cookie
  • WWW-Authenticate:用于401状态码响应,提供与服务器所支持的身份验证类型等信息
  • X-Frame-Options:指示浏览器Frame是否及如何加载当前响应

服务器使用Set-Cookie响应消息头向浏览器发布cookie信息,可以使用多个响应消息头发布多个cookie,浏览器也可使用Cookie请求消息头提交使用分号分隔的多个cookie信息给服务器

cookie具有名称、值、有效时间、有效域、有效路径、是否为https请求、是否可在客户端修改属性,可通过Set-Cookie响应消息头设置,参数列表如下:

  • expires:指定cookie有效时间,若未指定则表示只保存在当前浏览器回话中
  • domain:指定cookie有效域,必须和收到cookie的域相同或者是其父域
  • path:指定cookie的有效url路径
  • secure:仅仅在https请求中提交cookie信息
  • httpOnly:用于指定在客户端是否可以通过js修改cookie信息

状态码

状态码用于说明请求结果,分为5大类:

  • 1XX:提供信息
  • 2XX:请求成功
  • 3XX:请求重定向
  • 4XX:请求包含错误
  • 5XX:服务器执行错误

常见状态码说明:

  • 100 Continue:当客户端提交一个包含主体的请求时,将发送该响应,表示已收到请求消息头,客户端继续发送主体
  • 200 OK:请求成功,且响应主体中包含请求结果
  • 201 Created:PUT请求的响应返回状态码,表示请求成功提交
  • 301 Moved Permanently:指示浏览器永久重定向到Location指定的URL,客户端使用新的URL替换原始URL
  • 302 Found:指示浏览器暂时重定向到Location指定的URL,客户端随后的请求恢复到原始URL
  • 304 Not Modified:指示浏览器使用缓存中保存的资源副本
  • 400 Bad Request:表示发起无效HTTP请求
  • 401 Unauthorized:服务器需要进行HTTP身份认证
  • 403 Forbidden:禁止访问请求资源
  • 404 Not Found:表示资源不存在
  • 405 Method Not Allowd:表示URL不支持请求方法
  • 413 Request Entity Too Large:表示请求主体过长,服务器无法处理
  • 413 Request URI Too Long:表示请求URL过长,服务器无法处理
  • 500 Internal Server Error:表示服务器执行遇到错误
  • 503 Service Unavailable:表示服务器运行正常,但无法做出响应

HTTPS

HTTP使用非加密的TCP作为传输机制,缺点在网络适当位置的攻击者能够截获发送内容,HTTPS和HTTP都属于应用层协议,当HTTPS通过安全传输机制-安全套接层(Secure Socket Layer,SSL)传输数据,可保护通过网络传输数据的机密性和完整性

SSL已经由TLS(Transport Layer Security,传输层安全)代替

HTTP代理

代理服务器运行在客户端浏览器和web服务器之间,浏览器将所有请求提交给代理服务器,代理服务器将请求传送给相关web服务器,并将响应返回给浏览器

HTTP代理服务器工作机制:

  • 当浏览器向代理服务器发送HTTP请求时,代理服务器将完整URL插入请求中,代理服务器将提取主机名和端口,并使用这些信息将请求指向正确的目标web服务器
  • 当浏览器向代理服务器发送HTTPS请求时,浏览器将代理作为TCP级中继,浏览器使用CONNECT方法向代理服务器提交一个HTTP请求,并指定URL中的目标主机名称和端口号,从而建立中继。若代理允许该请求,则返回200状态码的HTTP响应,一直开放TCP链接,从此以后作为目标web服务器的TCP级中继

HTTP身份认证

HTTP具有自己的用户身份验证机制,主要方案由:

  • Basic:在请求消息头中随每条消息以Base64编码字符串的形式发送用户证书
  • NTLM:是质询-响应式机制,使用Windows NTLM协议版本
  • Digest:是质询-响应式机制,随同用户证书一起使用一个随机值的MD5校验和

简介

logging模块是python日志管理模块

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
In [19]: import logging

In [20]: logging.critical('this is critical msg')
CRITICAL:root:this is critical msg

In [21]: logging.error('this is error msg')
ERROR:root:this is error msg

In [22]: logging.warning('this is warning msg')
WARNING:root:this is warning msg

In [23]: logging.info('this is info msg')

In [24]: logging.debug('this is debug msg')

日志级别:

CRITICAL > ERROR > WARNING(默认) > INFO > DEBUG > NOTSET

默认日志格式:

LOGLEVEL:LOGGERNAME:msg

日志级别,日志格式,输出位置设置

使用logging.basicConfig进行日志输出信息配置

1
2
3
4
5
6
logging.basicConfig(level=logging.DEBUG,
format='',
datefmt='',
filemode='',
filename=''
)

参数说明:

1.level:指定日志记录级别,可选值logging.ERROR/WARNING/INFO/DEBUG
2.format:指定日志输出格式:

参数 说明
%(name)s Logger的名字
%(levelno)s 数字日志级别
%(levelname)s 文本日志级别
%(pathname)s 调用日志输出函数的模块文件路径
%(filenames)s 调用日志输出函数的模块文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数语句所在行号
%(created)f 当前时间
%(relativeCreated)d 当前时间
%(asctime)s 当前时间,格式’2015-05-28 20:50:03,345’
%(thread)d 线程id
%(threadName)s 线程名
%(process)d 进程id
%(message)s 消息

3.datefmt:指定日志中日期格式
4.filemode:指定文件打开方式
5.filename:指定日志文件位置
6.stream:制定stream创建StreamHandler,若同时存在filename和stream时,filename启用

logging.getLogger()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import logging

logger = logging.getLogger()

mlogger = logging.getLogger('com.uk.silence')
mlogger.setLevel(logging.INFO)

fh = logging.FileHandler('/tmp/test.log')

ch = logging.StreamHandler()

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s:%(message)s')

fh.setFormatter(formatter)
ch.setFormatter(formatter)

mlogger.addHandler(fh)
mlogger.addHandler(ch)

logger.info('this is info msg')
logger.error('this is error msg')

mlogger.debug('this is debug msg')
mlogger.info('this is info msg')

m2logger = logging.getLogger('com.uk.silence.child')

m2logger.debug('this is debug msg')
m2logger.info('this is info msg')

logger说明:
logging.getLogger为默认根logger,logger为树形结构, 在使用m2logger时并为设置hander、formatter、level,但其输出与mlogger相同,原因logger具有继承功能(按名称进行属性继承)

logger.Filter('com.uk.silence')用于定义filter功能,表示只有以com.uk.silence.child开头的logger进行信息输出,按示例若指定mlogger.addFilter(filter)后使用mlogger.error则不能输出日志

handler说明:

类型 说明
logging.StreamHandler 指定向流对象进行
logging.FileHandler 指定文件
logging.handlers.RotaingFileHandler 指定文件,但可管理文件大小,当超过指定值后则重新创建日志文件
logging.handlers.TimedRotatingFileHandler 指定文件,超过指定周期后重新创建日志文件
logging.handlers.SocketHandler 指定socket
logging.handlers.SyslogHandler 指定syslog服务器
logging.handlers.HTTPHandler 使用post/get请求提交数据到web服务器

logging.config.fileConfig

使用文件方式进行日志管理配置,配置文件格式如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[loggers]
keys=root,comuksilence,comuksilencechild

[handlers]

keys=file

[formatters]

keys=basic

[logger_root]

level=WARNING
handlers=file

[logger_comuksilence]

level=INFO
handlers=file
qualname=com.uk.silence
propagate=0

[logger_comuksilencecomchild]

qualname=com.uk.silence.child

[handler_file]

class=FileHandler
formatter=basic
args=('/tmp/test.log')

[formatter_basic]

format=%(asctime)s - %(name)s - %(levelname)s:%(message)s
datefmt=

简介

bpmappers库是将python对象转化为字典类型的库, 在对外提供数据服务类型的功能开发用途较大,尤其后台使用django开发,bpmappers库简便将对象转化为dict类型,配和json.dumps功能对外提供json格式数据

安装

pip install bpmappers

使用

  • 类中属性为的基本类型

类的定义:

1
2
3
4
5
6
7
8
9
10
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age

from bpmappers import Mapper, RawField

class PersonMapper(Mapper):
name = RawField('name')
age = RawField('age')

试验:

1
2
3
4
In [6]: me = Person('silence', 28)

In [7]: PersonMapper(me).as_dict()
Out[7]: {'age': 28, 'name': 'silence'}
  • 类中属性存在其他对象进行组合
1
2
3
4
5
6
7
8
9
10
class Blog(object):
def __init__(self, content, author):
self.content = content
self.author = author

from bpmappers import DelegateField

class BlogMapper(Mapper):
content = RawField('content')
author = DelegateField(PersonMapper, 'author')

试验:

1
2
3
4
In [27]: blog = Blog('bpmappers test', me)

In [28]: BlogMapper(blog).as_dict()
Out[28]: {'content': 'bpmappers test', 'author': {'age': 28, 'name': 'silence'}}
  • 类属性存在由其他对象组成的列表
1
2
3
4
5
6
7
8
9
10
from bpmappers import ListDelegateField

class Group(object):
def __init__(self, name, members):
self.name = name
self.members = members

class GroupMapper(Mapper):
name = RawField('name')
members = ListDelegateField(PersonMapper, 'members')

试验:

1
2
3
4
In [34]: group = Group('python', [me])

In [35]: GroupMapper(group).as_dict()
Out[35]: {'name': 'python', 'members': [{'age': 28, 'name': 'silence'}]}
  • 需要将列表或者基本类型进行加上key并转化dict
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

from bpmappers import NonKeyField, NonKeyDelegateField, NonKeyListDelegateField

class ValueMapper(Mapper):
value = NonKeyField()
def filter_value(self):
return str(self.data)

class ValueDelegateMapper(Mapper):
value = NonKeyDelegateField()
def filter_value(self):
return self.data

class ValueListDelegateMapper(Mapper):
value = NonKeyListDelegateField(PersonMapper)
def filter_value(self):
return self.data

试验:

1
2
3
4
5
6
7
8
9
10
11
12
In [45]: ValueMapper(1).as_dict()
Out[45]: {'value': '1'}

In [46]: ValueMapper([1]).as_dict()
Out[46]: {'value': '[1]'}

In [57]: ValueDelegateMapper(me).as_dict()
Out[57]: {'value': {'age': 28, 'name': 'silence'}}


In [61]: ValueListDelegateMapper([me]).as_dict()
Out[61]: {'value': [{'age': 28, 'name': 'silence'}]}
  • callback & after_callback & filter & after_filter & key_name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Value(object):
def __init__(self, value):
self.value = value


class ValueMapper(Mapper):
value = RawField('value',\
callback=lambda x:'(cb %s)' % x,\
after_callback=lambda x:'[after cb %s]' % x)

def filter_value(self, value):
return '&lt;filter %s&gt;' % value

def after_filter_value(self, value):
return '{after_filter %s}' % value

def key_name(self, name, value, field):
return 'namespace:%s' % name

试验:

1
2
In [77]: ValueMapper(Value('test')).as_dict()
Out[77]: {'namespace:value': '{after_filter [after cb (cb &lt;filter test&gt;)]}'}

执行顺序:
1.filter
2.callback
3.after_callback
4.after_filter

  • django model转化
1
2
3
4
5
6
from bpmappers import djangomodel

class PersonModelMapper(djangomodel.ModelMapper):
class Meta:
model=Person
exclude=['id']

试验:

1
In [77]: PersonModelMapper(Person.objects.get(pk=1)).as_dict()