【问题标题】:Python Requests - Chunked StreamingPython 请求 - 分块流式传输
【发布时间】:2017-06-13 23:26:32
【问题描述】:

由于服务器设计错误,如果我找到一个空字节,我将不得不向下传输 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+\d+\d+ 是什么意思 - 那是 \d+ 伪装成某种方式来破坏一些正则表达式引擎。

标签: python for-loop python-requests chunked-encoding


【解决方案1】:

首先,那个正则表达式搞砸了\d+ 表示“一个或多个数字”,那么为什么要将它们中的三个链接在一起呢?此外,您需要对这种模式使用“原始字符串”,因为\ 被视为转义字符,因此您的模式无法正确构建。你想把它改成re.search(r'"status":\d+}}', d)

其次,如果您的块中有两个换行符,您的d.split() 行可能会选择错误的\n

你甚至不需要正则表达式,好的 ol' Python 字符串搜索/切片足以确保你得到正确的分隔符:

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...

它看起来很复杂,但如果您逐行阅读它实际上很容易,并且您还必须使用正则表达式匹配来处理其中的一些复杂性(重叠匹配等)(考虑到同一块中潜在的多个事件分隔符)。

【讨论】:

  • 哇。这是我收到的最全面的答案。希望我能给你更多的积分!
猜你喜欢
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2010-09-24
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
相关资源
最近更新 更多