Mehrzeilige CSV-Datensätze mit Python Requests und csv.reader streamen
Streame eine Antwort über einen Proxy in csv.reader und erhalte Datensatzgrenzen, statt jede physische Zeile am Trennzeichen zu teilen.
stream=True ermöglicht den Verarbeitungsbeginn, bevor der Body einer Antwort über einen Proxy vollständig geladen ist. Für CSV übergib einen Iterator über Textzeilen an csv.reader, damit Trennzeichen in Anführungszeichen und mehrzeilige Datensätze CSV-Daten bleiben.
Für eine beispielhafte UTF-8-Datei mit Semikolons:
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
Wähle die tatsächliche Kodierung und den Dialekt der Datei. Für einen öffentlichen CSV-Download über eine zulässige öffentliche Proxy-Route bietet die HTTP-Proxy-Liste Kandidaten für die routes-URL. Diese Version normalisiert physische Zeilenenden zu LF: iter_lines entfernt sie, und der Generator fügt für den CSV-Parser wieder einen Zeilenumbruch hinzu. Das zählt, wenn ein Feld in Anführungszeichen auf einer weiteren physischen Zeile fortgesetzt wird.
Für Abläufe, die eine bytegenaue Erhaltung eingebetteter CRLF-Zeichen verlangen, nutze eine streamende Textumhüllung, die diese Zeilenenden erhält. Die bewusste Normalisierung des Beispiels eignet sich für datensatzorientierte Verarbeitung, bei der LF die gewünschte Darstellung ist.
Eine Antwort, viele Lesezugriffe
Der Iterator verbraucht Blöcke aus einer einzigen HTTP-Antwort. Er stellt keine neue Anfrage pro Zeile. HTTP-Range-Anfragen sind ein anderer Mechanismus und markieren Datensatzgrenzen von CSV nicht von selbst.
Ein Aufruf von response.text oder das Sammeln aller Zeilen in einer Liste würde den gesamten Inhalt zurück in den Speicher holen. Streaming braucht weiterhin Platz für Transportpuffer und den aktuellen Datensatz, der selbst ein großes Feld enthalten kann.
Der Antwortkontext schließt den Body beim Verlassen der Schleife, auch bei einem frühen Treffer. Das Lese-Timeout begrenzt das Warten auf eingehende Daten, nicht die Gesamtlaufzeit einer großen Dateiübertragung.