Python 요청 모듈로 PDF 파일 다운로드 및 저장


87

웹 사이트에서 PDF 파일을 다운로드하여 디스크에 저장하려고합니다. 내 시도가 인코딩 오류로 실패하거나 빈 PDF가 생성됩니다.

In [1]: import requests

In [2]: url = 'http://www.hrecos.org//images/Data/forweb/HRTVBSH.Metadata.pdf'

In [3]: response = requests.get(url)

In [4]: with open('/tmp/metadata.pdf', 'wb') as f:
   ...:     f.write(response.text)
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-4-4be915a4f032> in <module>()
      1 with open('/tmp/metadata.pdf', 'wb') as f:
----> 2     f.write(response.text)
      3 

UnicodeEncodeError: 'ascii' codec can't encode characters in position 11-14: ordinal not in range(128)

In [5]: import codecs

In [6]: with codecs.open('/tmp/metadata.pdf', 'wb', encoding='utf8') as f:
   ...:     f.write(response.text)
   ...: 

나는 그것이 어떤 종류의 코덱 문제라는 것을 알고 있지만 작동하도록 할 수 없습니다.

답변:


176

response.content이 경우에 사용해야합니다 .

with open('/tmp/metadata.pdf', 'wb') as f:
    f.write(response.content)

에서 문서 :

텍스트가 아닌 요청의 경우 응답 본문에 바이트로 액세스 할 수도 있습니다.

>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...

response.text, 출력을 문자열 객체로 반환하고 텍스트 파일을 다운로드 할 때 사용 합니다 . HTML 파일 등

그리고 response.content출력을 bytes 객체로 반환하고 바이너리 파일을 다운로드 할 때 사용 합니다 . PDF 파일, 오디오 파일, 이미지 등


response.raw대신 사용할 수도 있습니다 . 그러나 다운로드하려는 파일이 큰 경우 사용하십시오. 다음은 문서에서도 찾을 수있는 기본 예입니다.

import requests

url = 'http://www.hrecos.org//images/Data/forweb/HRTVBSH.Metadata.pdf'
r = requests.get(url, stream=True)

with open('/tmp/metadata.pdf', 'wb') as fd:
    for chunk in r.iter_content(chunk_size):
        fd.write(chunk)

chunk_size사용하려는 청크 크기입니다. 로 설정하면 2000요청이 해당 파일을 첫 번째 2000바이트로 다운로드하고 파일 에 쓰고 완료하지 않는 한 반복해서 수행합니다.

따라서 RAM을 절약 할 수 있습니다. 하지만 response.content이 경우 파일이 작기 때문에 대신 사용하는 것이 좋습니다. 보시다시피 사용 response.raw은 복잡합니다.


관련 :


좋습니다. response.raw에 대한 추가 정보를 제공해 주셔서 감사합니다.
Jim

23

Python 3에서는 pathlib가 가장 쉬운 방법이라는 것을 알았습니다. 요청의 response.content 는 pathlib의 write_bytes와 잘 어울립니다.

from pathlib import Path
import requests
filename = Path('metadata.pdf')
url = 'http://www.hrecos.org//images/Data/forweb/HRTVBSH.Metadata.pdf'
response = requests.get(url)
filename.write_bytes(response.content)

1
게시 해주셔서 감사합니다. 원래 질문은 Python 2.7 이었지만 이제는 Python 3을 사용하고 있습니다. pathlib 라이브러리 [버전 3.4의 새로운 기능]에 대해 몰랐으며 현재 프로젝트에 통합 할 것입니다.
Jim

그것은주고 544파일이 깨졌습니다, 어떤 아이디어?
ahbon

@ahbon, 무슨 뜻이야?
user6481870

14

urllib를 사용할 수 있습니다.

import urllib.request
urllib.request.urlretrieve(url, "filename.pdf")

1
이것은 최고입니다, tbh.
Dhaval Savalia

이 사람은 최고입니다
roktim

1
urlretrieve요청 헤더를 결정하기 위해 전역 설정에 의존하므로 일부 사용 사례에는 적합하지 않습니다.
Michael Crenshaw

5

일반적으로 이것은 Python3에서 작동합니다.

import urllib.request 
..
urllib.request.get(url)

urllib 및 urllib2는 Python2 이후에 제대로 작동하지 않습니다.

신비한 경우에 요청이 작동하지 않는 경우 (저와 함께 발생)

wget.download(url)

관련 :

다음은 웹 페이지에서 모든 pdf 파일을 찾아 다운로드하는 적절한 설명 / 솔루션입니다.

https://medium.com/@dementorwriter/notesdownloader-use-web-scraping-to-download-all-pdfs-with-python-511ea9f55e48


2

나는 초보자입니다. 내 솔루션이 잘못된 경우 언제든지 수정 및 / 또는 알려주십시오. 나도 새로운 것을 배울 수 있습니다.

내 솔루션 :

파일을 저장할 위치 에 따라 downloadPath를 변경하십시오 . 절대 경로를 사용하여 자유롭게 사용하십시오.

아래를 downloadFile.py로 저장하십시오.

용법: python downloadFile.py url-of-the-file-to-download new-file-name.extension

확장자를 추가하는 것을 잊지 마십시오!

사용 예 : python downloadFile.py http://www.google.co.uk google.html

import requests
import sys
import os

def downloadFile(url, fileName):
    with open(fileName, "wb") as file:
        response = requests.get(url)
        file.write(response.content)


scriptPath = sys.path[0]
downloadPath = os.path.join(scriptPath, '../Downloads/')
url = sys.argv[1]
fileName = sys.argv[2]      
print('path of the script: ' + scriptPath)
print('downloading file to: ' + downloadPath)
downloadFile(url, downloadPath + fileName)
print('file downloaded...')
print('exiting program...')

Pawel, 답변 해 주셔서 감사합니다. 이 질문을 처음 게시했을 때 저는 Python 초보자였습니다. 이제 나는 그 언어를 아주 잘 알고 있습니다. 명령 줄에서 파일을 다운로드하기 위해 Python 스크립트를 작성하는 사용 사례는 wget 또는 curl과 같은 유틸리티로 처리 할 수 ​​있습니다. 또한 게시 된 함수 downloadFile이 자신을 호출하는 것 같습니다. 두 번째 코드 블록을 들여 쓰려고 했습니까? stackoverflow에서 당신은 그것을 밖으로 들여 쓰기하여 수정할 수 있습니다. 또한 Python의 argparse 라이브러리를 살펴 보도록 제안하고 싶습니다. 이를 사용하여 멋진 명령 줄 유틸리티를 만들 수 있습니다. 매개 변수를 처리합니다.
Jim

파일 쓰기를 처리하기 위해 컨텍스트 관리자 (열기 ... 파일로 : 등)를 사용하는 것이 좋습니다. 코드가 깔끔하게 작성되었습니다. 당신은 파이썬을 배우는 좋은 길을 가고 있습니다. 행운을 빕니다!
Jim

1
답장 해 주셔서 감사합니다, @Jim! 나는 포스트를 편집했고 실제로 나는 프로그램의 주요 부분 인 "들여 쓰기를 의도하지 않았다". 귀하의 조언에 감사드립니다! :)
Duck Ling

-4

폴더에 쓰기에 대한 Kevin 답변과 관련하여 tmp다음과 같아야합니다.

with open('./tmp/metadata.pdf', 'wb') as f:
    f.write(response.content)

그는 .당신의 폴더 tmp가 이미 만들어 졌어 야 하는 주소와 과정 을 잊었습니다.


5
1- Kevin은 작성하려는 아이디어를 얻지 못했습니다 tmp. OP의 질문과 같았습니다. 2 - /tmp디렉토리에있는 유닉스 시스템에서의 tmp입니다 /tmp아니,.
realUser404
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.