2014-07-23 7 views
3

한 사이트에서 다른 사이트로 파일을 전송하는 코드를 작성하고 싶습니다. 이것은 큰 파일이 될 수 있으며 로컬 임시 파일을 만들지 않고 그것을하고 싶습니다.Python urllib2를 사용하여 어떻게 GET과 POST간에 스트리밍 할 수 있습니까?

mmap을 사용하여 파이썬에서 큰 파일을 업로드하는 트릭을 보았습니다. "HTTP 스트리밍으로 큰 파일 게시"하지만 실제로 필요한 것은 GET에서 POST를 작성하는 응답을 연결하는 방법입니다.

누구나 전에이 작업을 수행 했습니까?

+1

"큰"은 "너무 커서 메모리에 적합하지 않다"는 뜻입니다. 왜냐하면 우리가 단지 200MB 또는 그 이상을 말하는 것이기 때문에, 임시 파일을 만드는 것을 피하는 쉬운 방법은 단지 메모리에'read()'하고, 그것을 임시 파일에 쓰지 않고 단지 문자열을 다른 요청에 보내는 것입니다. – abarnert

답변

0

urllib2가이 작업에 너무 간단 할 수 있습니다. 당신은 pycurl을 들여다 볼 수 있습니다. 스트리밍을 지원한다는 것을 알고 있습니다.

3

당신은 할 수 없거나 그렇게해서는 안됩니다.

urllib2 요청 개체에는 즉시 데이터를 스트림 할 수있는 방법이 없습니다. 다른 방향에서 응답 객체는 파일과 비슷한 객체이므로 이론상 read() 대신 read(8192)을 사용할 수 있지만 HTTP를 비롯한 대부분의 프로토콜에서는 응답을 메모리로 읽어 들여 항상 read(8192)은 버퍼를 호출하여 무의미합니다. 따라서 요청을 가로 채고 소켓을 훔쳐서 수동으로 처리해야합니다.이 시점에서 urllib2이 도움이되는 것보다 더 많은 것을 얻고 있습니다.

urllib2은 몇 가지 일을 쉬워 보이고, 어떤 일은해야 할 일보다 훨씬 힘들고, 불가능한 일은 몇 가지 일을 만듭니다. 쉬운 일이 아니라면 사용을 중지하십시오.


한 가지 해결책은 더 높은 수준의 타사 라이브러리를 사용하는 것입니다. 예를 들어, requests은 중간에 있습니다 (응답에서 스트리밍하는 것이 매우 쉽지만 제한된 상황에서만 응답으로 스트리밍 할 수 있음). requests-toolbelt을 사용하면 나머지 방법을 사용할 수 있습니다. 스트림 업로드).


다른 해결책은 하위 레벨 라이브러리를 사용하는 것입니다. 그리고 여기에서는 stdlib를 떠나지 않아도됩니다. httplib은 비트 단위로 보내고받는 관점에서 생각하도록 강요하지만 정확히 원하는 것입니다. 요청을받을 때 connectrequest을 호출 한 다음 read(8192)을 응답 개체에 반복해서 호출 할 수 있습니다. 게시 요청에서 connect, putrequest, putheader, endheaders을 호출 한 다음 반복적으로 send 각 버퍼를 가져온 다음 완료하면 getresponse을 호출합니다. 사실

, 파이썬 3.2 +의 http.client (2.x에서의 httplib에 해당), HTTPClient.request 문자열을 할 필요가 없습니다, 어떤 반복자 또는 readfileno있는 모든 파일 - 류의 객체가 될 수 있습니다 ... 응답 개체가 포함되어 있습니다. 아마 당신은 (당신이 실제로 보내 Request 객체를 구축 urllib.request, urllib2의 3.X 버전을 사용할 수 없습니다 적절한 헤더 공예하려는 물론, 제외 ...

import http.client 

getconn = httplib.HTTPConnection('www.example.com') 
getconn.request('GET', 'http://www.example.com/spam') 
getresp = getconn.getresponse() 

getconn = httplib.HTTPConnection('www.example.com') 
getconn.request('POST', 'http://www.example.com/eggs', body=getresp) 
getresp = getconn.getresponse() 

: 그래서,이 간단 그것 ...), 하드 코드 대신 urlparse을 사용하여 URL에서 호스트와 포트를 가져 와서 POST 요청의 응답을 없애거나 적어도 확인하고 싶습니다. 그러나 이것은 어려운 부분을 보여 주며 어렵지 않습니다.

불행히도 2.x에서는 작동하지 않는다고 생각합니다. 당신이 libcurl에 익숙하다면


마지막으로, (소스 배포판과 함께 제공 포함)이 적어도 세 래퍼가있다. libcurlurllib2보다 더 높은 레벨 또는 낮은 레벨로 호출할지 여부는 확실하지 않습니다. 이는 그 자체의 이상한 복잡성 축에 있습니다. :)

+0

파이썬 3을 추진해야한다고 생각합니다. 정말 매력적으로 보입니다. –

관련 문제