Python 请求 - 分块流
Python Requests - Chunked Streaming
由于服务器设计错误,我不得不向下传输 JSON 并更正一个空字节(如果找到的话)。我正在使用 python requests
来执行此操作。每个 JSON 事件都由 \n
分隔。我在这里要做的是拉下一大块(总是少于一个日志行)。在该块中搜索事件指示符的结尾 ("\"status\":\d+\d+\d+}}\n"
)。
如果那个指示符存在,我将对整个 JSON 事件做一些事情,如果没有,我将该块添加到缓冲区,b
,然后获取下一个块并寻找标识符。一旦我记下这个,我就会开始搜索空字节。
b = ""
for d in r.iter_content(chunk_size=25):
s = re.search("\"status\":\d+\d+\d+}}\n", d)
if s:
d = d.split("\n", 1)
fullLogLine = b + d[0]
b = d[1]
else:
b = b + d
在这种情况下,我完全失去了 b 的价值。它似乎不会延续到 iter_content
。每当我尝试打印 b
的值时,它都是空的。我觉得我在这里遗漏了一些明显的东西。什么都有帮助。谢谢。
首先,正则表达式搞砸了 \d+
意思是 'one or more digits' 那么为什么要将它们三个链接在一起呢?此外,您需要使用 'raw string' 来对模式进行排序,因为 \
被视为转义字符,因此您的模式无法正确构建。您想要将其更改为 re.search(r'"status":\d+}}', d)
.
其次,如果您的块中有两个换行符,您的 d.split()
行可能会出现错误 \n
。
你甚至不需要正则表达式,好的 Python 字符串 search/slicing 足以确保你得到正确的分隔符:
logs = [] # store for our individual entries
buffer = [] # buffer for our partial chunks
for chunk in r.iter_content(chunk_size=25): # read chunk-by-chunk...
eoe = chunk.find("}}\n") # seek the guaranteed event delimiter
while eoe != -1: # a potential delimiter found, let's dig deeper...
value_index = chunk.rfind(":", 0, eoe) # find the first column before it
if eoe-1 >= value_index >= eoe-4: # woo hoo, there are 1-3 characters between
try: # lets see if it's a digit...
status_value = int(chunk[value_index+1:eoe]) # omg, we're getting there...
if chunk[value_index-8:value_index] == '"status"': # ding, ding, a match!
buffer.append(chunk[:eoe+2]) # buffer everything up to the delimiter
logs.append("".join(buffer)) # flatten the buffer and write it to logs
chunk = chunk[eoe + 3:] # remove everything before the delimiter
eoe = 0 # reset search position
buffer = [] # reset our buffer
except (ValueError, TypeError): # close but no cigar, ignore
pass # let it slide...
eoe = chunk.find("}}\n", eoe + 1) # maybe there is another delimiter in the chunk...
buffer.append(chunk) # add the current chunk to buffer
if buffer and buffer[0] != "": # there is still some data in the buffer
logs.append("".join(buffer)) # add it, even if not complete...
# Do whatever you want with the `logs` list...
它看起来很复杂,但如果你逐行阅读它实际上很容易,你将不得不做一些复杂性(重叠匹配等)正则表达式也匹配(以考虑同一块中潜在的多个事件定界符)。
由于服务器设计错误,我不得不向下传输 JSON 并更正一个空字节(如果找到的话)。我正在使用 python requests
来执行此操作。每个 JSON 事件都由 \n
分隔。我在这里要做的是拉下一大块(总是少于一个日志行)。在该块中搜索事件指示符的结尾 ("\"status\":\d+\d+\d+}}\n"
)。
如果那个指示符存在,我将对整个 JSON 事件做一些事情,如果没有,我将该块添加到缓冲区,b
,然后获取下一个块并寻找标识符。一旦我记下这个,我就会开始搜索空字节。
b = ""
for d in r.iter_content(chunk_size=25):
s = re.search("\"status\":\d+\d+\d+}}\n", d)
if s:
d = d.split("\n", 1)
fullLogLine = b + d[0]
b = d[1]
else:
b = b + d
在这种情况下,我完全失去了 b 的价值。它似乎不会延续到 iter_content
。每当我尝试打印 b
的值时,它都是空的。我觉得我在这里遗漏了一些明显的东西。什么都有帮助。谢谢。
首先,正则表达式搞砸了 \d+
意思是 'one or more digits' 那么为什么要将它们三个链接在一起呢?此外,您需要使用 'raw string' 来对模式进行排序,因为 \
被视为转义字符,因此您的模式无法正确构建。您想要将其更改为 re.search(r'"status":\d+}}', d)
.
其次,如果您的块中有两个换行符,您的 d.split()
行可能会出现错误 \n
。
你甚至不需要正则表达式,好的 Python 字符串 search/slicing 足以确保你得到正确的分隔符:
logs = [] # store for our individual entries
buffer = [] # buffer for our partial chunks
for chunk in r.iter_content(chunk_size=25): # read chunk-by-chunk...
eoe = chunk.find("}}\n") # seek the guaranteed event delimiter
while eoe != -1: # a potential delimiter found, let's dig deeper...
value_index = chunk.rfind(":", 0, eoe) # find the first column before it
if eoe-1 >= value_index >= eoe-4: # woo hoo, there are 1-3 characters between
try: # lets see if it's a digit...
status_value = int(chunk[value_index+1:eoe]) # omg, we're getting there...
if chunk[value_index-8:value_index] == '"status"': # ding, ding, a match!
buffer.append(chunk[:eoe+2]) # buffer everything up to the delimiter
logs.append("".join(buffer)) # flatten the buffer and write it to logs
chunk = chunk[eoe + 3:] # remove everything before the delimiter
eoe = 0 # reset search position
buffer = [] # reset our buffer
except (ValueError, TypeError): # close but no cigar, ignore
pass # let it slide...
eoe = chunk.find("}}\n", eoe + 1) # maybe there is another delimiter in the chunk...
buffer.append(chunk) # add the current chunk to buffer
if buffer and buffer[0] != "": # there is still some data in the buffer
logs.append("".join(buffer)) # add it, even if not complete...
# Do whatever you want with the `logs` list...
它看起来很复杂,但如果你逐行阅读它实际上很容易,你将不得不做一些复杂性(重叠匹配等)正则表达式也匹配(以考虑同一块中潜在的多个事件定界符)。