Python 扩展CGIHTTPRequestHandler或BaseHTTPRequestHandler。解析请求的最佳实践
我正在考虑向使用Python构建的守护进程添加集成HTTP接口的想法。我喜欢这种方法,因为它使整个守护程序代码可移植(而不是有单独的web部分和cli部分) 一切都很好,但我想知道在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
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的更详细答案