[t:/]$ 지식_

파이썬 requests line by line 처리

2018/11/06

http로 파일을 땡겨올 때, 스트리밍으로 처리하고 싶을 때가 있다. 예를 들어 가져오는 파일이 겁나 크다면, 그걸 다 파일로 저장하고 나서 처리하거나, 메모리에 때려넣고 처리하거나 여튼 문제다. 멀티쓰레드 걸고 하면 메모리 문제도 그렇고 tempfile 쓰는 것도 다 받고 나서 처리해야 하고 뭐 그렇다. iter_lines()로 간단히 해결되는데, 스택 오버 플로우고 뭐고 파이썬이 php와는 결이 다르다고는 하나, 쉽다는 이유 하나로 phpschool화 되어가는 것은 아닌지 이제 정답을 찾기가 꽤 어렵다.

아래 코드는 방금 짠 테스트 코드인데, csv 파싱을 위해 csv 모듈을 일일히 콜하고 있다는 불합리성은 일단 제껴두고-_- iter_lines만 보면 된다. 관측결과 실제로도 http 응답을 받으면서 바로바로 처리하고 있다. (http chunked 참조)


    def get_url_csv(self):
        debug_log('csv 다운로드 시작 : ', self.dbg)
        url = self.metas['url'].split('?')

        res = requests.get(url[0], stream=True, params=url[1], proxies=proxyDict)

        if res.status_code != 200:
            debug_log('csv 다운로드 실패 : ', self.dbg)    
            exit(-1)

        first = True

        count = 0
        for r in res.iter_lines(chunk_size=4096):
            line = list(csv.reader([r], delimiter = ','))[0]
            if first:
                first = False
                fields_idx = self.get_field_idx(line)
                continue

            out = self.parse_func(line, fields_idx)
            if out is not None:
                print out

            count += 1

        debug_log('csv 다운로드 라인 : ', str(self.metas['lines_exported']) + ' / ' + self.dbg)
        debug_log('csv 처리 라인 : ', str(count) + ' / ' + self.dbg)

        if self.metas['lines_exported'] != count:
            debug_log('[WARN] csv 처리 라인 불일치!!!! : ', self.dbg)

        res.connection.close()








[t:/] is not "technology - root". dawnsea, rss