Transmitir registos CSV de várias linhas com Python Requests e csv.reader
Transmita uma resposta através de um proxy para csv.reader e preserve os limites dos registos em vez de dividir cada linha física no delimitador.
stream=True permite que o processamento comece antes de o corpo de uma resposta através de um proxy estar totalmente descarregado. Para CSV, passe um iterador de linhas de texto ao csv.reader para que os delimitadores entre aspas e os registos de várias linhas continuem a ser dados CSV.
Para um ficheiro UTF-8 ilustrativo com pontos e vírgulas:
import csv
import requests
routes = {'https': 'http://proxy.example:8080'}
with requests.get(
'https://data.example/observations.csv',
proxies=routes,
stream=True,
timeout=(5, 30),
) as response:
response.raise_for_status()
response.encoding = 'utf-8'
lines = (
line + '\n'
for line in response.iter_lines(
chunk_size=65536, decode_unicode=True)
)
for record in csv.reader(lines, delimiter=';'):
if record and record[0] == 'wanted':
print(record)
break
Escolha a codificação e o dialeto reais do ficheiro. Para um download público de CSV numa rota de proxy público permitida, a lista de proxies HTTP fornece candidatos para o URL routes. Esta versão normaliza os fins de linha físicos para LF: o iter_lines remove-os e o gerador acrescenta novamente uma nova linha para o analisador CSV. Isso importa quando um campo entre aspas continua noutra linha física.
Para fluxos de trabalho que exigem preservação byte a byte dos caracteres CRLF incorporados, use um invólucro de texto em streaming que preserve esses fins de linha. A normalização deliberada do exemplo adequa-se ao processamento orientado a registos em que LF é a representação pretendida.
Uma resposta, muitas leituras
O iterador consome blocos de uma única resposta HTTP. Não emite um novo pedido por cada linha. Os pedidos HTTP Range são outro mecanismo e não identificam naturalmente os limites dos registos CSV.
Chamar response.text ou reunir todas as linhas numa lista traria todo o conteúdo de volta para a memória. O streaming continua a precisar de espaço para os buffers de transporte e o registo atual, que pode ele próprio conter um campo grande.
O contexto da resposta fecha o corpo quando o ciclo termina, incluindo numa correspondência precoce. O tempo limite de leitura limita a espera por dados recebidos, não a vida total de uma transferência de ficheiro grande.