Python 扩展CGIHTTPRequestHandler或BaseHTTPRequestHandler。解析请求的最佳实践

Python 扩展CGIHTTPRequestHandler或BaseHTTPRequestHandler。解析请求的最佳实践,python,parsing,Python,Parsing,我正在考虑向使用Python构建的守护进程添加集成HTTP接口的想法。我喜欢这种方法,因为它使整个守护程序代码可移植(而不是有单独的web部分和cli部分) 一切都很好,但我想知道在do\u GET方法中解析实际请求的最佳实践 这是我的原型do\u GET方法 def do_GET(self): str = "OK" print self.request self.send_response(200) self.send_heade

我正在考虑向使用Python构建的守护进程添加集成HTTP接口的想法。我喜欢这种方法,因为它使整个守护程序代码可移植(而不是有单独的web部分和cli部分)

一切都很好,但我想知道在
do\u GET
方法中解析实际请求的最佳实践

这是我的原型
do\u GET
方法

def do_GET(self):
        str = "OK"
        print self.request
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-length", len(str))
        self.end_headers()
        self.wfile.write(str)
收到请求时,
request
属性包含以下字符串

127.0.0.1---[15/Jan/2014 10:21:23]“GET/”200-

有没有一个标准库可以用来解析这个字符串?我认为我需要编写的自定义解析器首先使用
-
作为分隔符标记字符串,然后使用某种正则表达式处理第三个元素,该正则表达式匹配请求日期的
[([^\]+)]
,以及请求路径的
“[[^\]+”

我担心编写一个自定义解析器,因为我可能会遇到所有的异常。所以我想了解一下任何python标准的解析方法


谢谢您的时间。

就是这样一个库,可以帮助您解析HTTP头。

如果您能找到一个解析这些字符串的可靠库,那显然是您最好的选择

如果失败,如果您想尝试使用
pyparsing
的解决方案,这可能会帮助您开始:

import re
from pyparsing import Combine, Literal, Regex, White, Word
from pyparsing import alphanums, alphas, nums

data = '127.0.0.1 - - [15/Jan/2014 10:21:23] "GET /" 200 -'

ip_octet = Word(nums, min=1, max=3)
ip_sep = Literal('.')
ip = Combine(ip_octet + ip_sep
             + ip_octet + ip_sep
             + ip_octet + ip_sep
             + ip_octet)

day = Word(nums, min=1, max=2)
month = Word(alphas, exact=3)
year = Word(nums, exact=4)
date_sep = Literal('/')
date = Combine(day + date_sep
               + month + date_sep
               + year)
hms = Word(nums, min=1, max=2)
time_sep = Literal(':')
time = Combine(hms + time_sep
               + hms + time_sep
               + hms)
datetime = Literal('[').suppress() + date + time + Literal(']').suppress()

method = Word(alphas) # GET, etc
# path characters per RFC 1738 / <http://stackoverflow.com/a/1856809/1535629>
path = Word(alphanums + "$-_.+!*'(),/%")
req_enclosure = Literal('"').suppress()
req = req_enclosure + method + path + req_enclosure

code = Word(nums, exact=3) # HTTP status code

nodash = Literal('-').suppress()
parser = ip + nodash + nodash + datetime + req + code + nodash

result = parser.parseString(data)
print(result)
当然,它比使用
re
要详细得多,但在我看来,它更具可读性和可维护性


另外,如果需要,可以在
pyparsing
中使用正则表达式,如下所示:

import re
from pyparsing import Regex

data = '127.0.0.1'

ip_re = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
ip = Regex(ip_re)

result = ip.parseString(data)
print(result)
结果:

['127.0.0.1', '15/Jan/2014', '10:21:23', 'GET', '/', '200']
['127.0.0.1']

这使您可以选择以您认为最方便的方式混合和匹配正则表达式和
pyparsing
特性。

好的,通过进一步的调查,我发现
cgihtprequesthandler
有一个名为
path
的属性名。因此,按如下方式更改
do\u GET
方法为我提供了帮助期望的结果

def do_GET(self):

        str = "OK"

        print self.path

        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-length", len(str))
        self.end_headers()
        self.wfile.write(str)
输出

/send/message

当用<代码> >获取/发送/消息< /代码>

如果您发现无法找到能够解析这些字符串的库,请考虑使用,而不是使用正则表达式,以提高鲁棒性。@ ShansHin OK,谢谢您的提示,我会检查一下。我不相信这是我正在寻找的。我遇到的请求字符串没有A。ny头信息,当通过标准http服务器提供python脚本时,您建议的库似乎与头解析一起使用。+1感谢您提供关于pyparsing的更详细答案