Python Requests와 csv.reader로 여러 줄 CSV 레코드 스트리밍하기
프록시를 거친 응답을 csv.reader로 스트리밍하고, 각 물리적 줄을 구분자에서 나누는 대신 레코드 경계를 보존합니다.
stream=True를 사용하면 프록시를 거친 응답 본문이 완전히 다운로드되기 전에 처리를 시작할 수 있습니다. CSV의 경우 텍스트 줄 이터레이터를 csv.reader에 넘기면 따옴표 안의 구분자와 여러 줄에 걸친 레코드가 CSV 데이터로 유지됩니다.
세미콜론을 사용하는 예시 UTF-8 파일의 경우:
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
파일의 실제 인코딩과 방언을 선택하세요. 허용된 공용 프록시 경로로 공용 CSV를 내려받을 때는 HTTP 프록시 목록이 routes URL의 후보를 제공합니다. 이 버전은 물리적 줄 끝을 LF로 정규화합니다. iter_lines가 그것을 제거하고 생성기가 CSV 파서를 위해 줄바꿈을 다시 붙입니다. 따옴표 안의 필드가 다른 물리적 줄로 이어질 때 이 점이 중요합니다.
내장된 CRLF 문자를 바이트 단위로 정확히 보존해야 하는 워크플로에서는 그 줄 끝을 유지하는 스트리밍 텍스트 래퍼 구성을 사용하세요. 예시의 의도적 정규화는 LF가 의도된 표현인 레코드 중심 처리에 적합합니다.
하나의 응답, 여러 번의 읽기
이터레이터는 하나의 HTTP 응답에서 청크를 소비합니다. 줄마다 새 요청을 보내지 않습니다. HTTP Range 요청은 다른 메커니즘이며 CSV 레코드 경계를 자연스럽게 식별하지 않습니다.
response.text를 호출하거나 모든 행을 목록에 모으면 전체 내용이 다시 메모리로 돌아옵니다. 스트리밍도 전송 버퍼와 현재 레코드를 위한 공간이 필요하며, 레코드 자체가 큰 필드를 담을 수 있습니다.
응답 컨텍스트는 루프를 벗어날 때 본문을 닫습니다. 조기 일치의 경우에도 마찬가지입니다. 읽기 타임아웃은 들어오는 데이터를 기다리는 시간을 제한하며, 큰 파일 전송의 전체 수명을 제한하지는 않습니다.