복붙노트

[PYTHON] 파이썬 urllib / urllib2를 사용하여 파일을 업로드하는 http POST 요청을 작성하십시오.

PYTHON

파이썬 urllib / urllib2를 사용하여 파일을 업로드하는 http POST 요청을 작성하십시오.

파이썬을 사용하여 파일을 웹 서비스에 업로드하고 응답을 얻으려는 POST 요청을하고 싶습니다. 예를 들어 curl을 사용하여 다음 POST 요청을 수행 할 수 있습니다.

curl -F "file=@style.css" -F output=json http://jigsaw.w3.org/css-validator/validator

어떻게 파이썬 urllib / urllib2로 같은 요청을 할 수 있습니까? 지금까지 가장 가까운 것은 다음과 같습니다.

with open("style.css", 'r') as f:
    content = f.read()
post_data = {"file": content, "output": "json"}
request = urllib2.Request("http://jigsaw.w3.org/css-validator/validator", \
                          data=urllib.urlencode(post_data))
response = urllib2.urlopen(request)

위의 코드에서 HTTP 오류 500이 발생했습니다. 하지만 내 컬 명령이 성공했기 때문에 파이썬 요청에 문제가있는 것입니까?

신참 질문에 아주 간단한 답변이나 실수가 있다면 나는이 주제에 대해 아주 처음이다. 모든 도움을 미리 보내 주셔서 감사합니다!

해결법

  1. ==============================

    1.개인적으로 나는 파일을 게시하기 위해 요청 라이브러리를 고려해야한다고 생각한다.

    개인적으로 나는 파일을 게시하기 위해 요청 라이브러리를 고려해야한다고 생각한다.

    url = 'http://jigsaw.w3.org/css-validator/validator'
    files = {'file': open('style.css')}
    response = requests.post(url, files=files)
    

    urllib2를 사용하여 파일을 업로드하는 것은 불가능하지만 복잡한 작업입니다. http://pymotw.com/2/urllib2/#uploading-files

  2. ==============================

    2.주변을 파고 들자 마자이 문제가 해결 된 것 같습니다. 멀티 파트 엔코더 설정이 제대로되어 있어야합니다.

    주변을 파고 들자 마자이 문제가 해결 된 것 같습니다. 멀티 파트 엔코더 설정이 제대로되어 있어야합니다.

    from poster.encode import multipart_encode
    from poster.streaminghttp import register_openers
    import urllib2
    
    register_openers()
    
    with open("style.css", 'r') as f:
        datagen, headers = multipart_encode({"file": f})
        request = urllib2.Request("http://jigsaw.w3.org/css-validator/validator", \
                                  datagen, headers)
        response = urllib2.urlopen(request)
    
  3. ==============================

    3.음, 여러 가지 방법이 있습니다. 위에서 언급했듯이 "multipart / form-data"형식으로 파일을 보낼 수 있습니다. 그러나 대상 서비스에서이 유형을 기대하지 않을 수도 있습니다.이 경우 좀 더 많은 방법을 시도해 볼 수 있습니다.

    음, 여러 가지 방법이 있습니다. 위에서 언급했듯이 "multipart / form-data"형식으로 파일을 보낼 수 있습니다. 그러나 대상 서비스에서이 유형을 기대하지 않을 수도 있습니다.이 경우 좀 더 많은 방법을 시도해 볼 수 있습니다.

    파일 객체를 전달하십시오.

    urllib2는 파일 객체를 데이터로 받아 들일 수 있습니다. 이 유형을 전달하면 라이브러리는 파일을 2 진 스트림으로 읽고이를 전송합니다. 그러나 적절한 Content-Type 헤더를 설정하지 않습니다. 또한 Content-Length 헤더가 누락 된 경우 파일에 존재하지 않는 객체의 len 속성에 액세스하려고 시도합니다. 즉, 메서드를 작동 시키려면 Content-Type 및 Content-Length 헤더를 모두 제공해야합니다.

    import os
    import urllib2
    
    filename = '/var/tmp/myfile.zip'
    headers = {
        'Content-Type': 'application/zip',
        'Content-Length': os.stat(filename).st_size,
    }
    request = urllib2.Request('http://localhost', open(filename, 'rb'),
                              headers=headers)
    response = urllib2.urlopen(request)
    

    파일 객체를 감싸기

    길이를 다루지 않으려면 간단한 래퍼 객체를 만들면됩니다. 조금 변경하면 파일을 메모리에로드 한 경우 문자열에서 내용을 가져올 수 있습니다.

    class BinaryFileObject:
      """Simple wrapper for a binary file for urllib2."""
    
      def __init__(self, filename):
        self.__size = int(os.stat(filename).st_size)
        self.__f = open(filename, 'rb')
    
      def read(self, blocksize):
        return self.__f.read(blocksize)
    
      def __len__(self):
        return self.__size
    

    콘텐츠를 base64로 인코딩

    또 다른 방법은 base64.b64encode를 통해 데이터를 인코딩하고 Content-Transfer-Type : base64 헤더를 제공하는 것입니다. 그러나이 방법을 사용하려면 서버 측에서 지원해야합니다. 구현에 따라 서비스는 파일을 수락하고 잘못 저장하거나 HTTP 400을 반환 할 수 있습니다. GitHub API는 오류를 발생시키지 않지만 업로드 된 파일은 손상됩니다.

  4. from https://stackoverflow.com/questions/27050399/make-an-http-post-request-to-upload-a-file-using-python-urllib-urllib2 by cc-by-sa and MIT license