簡體   English   中英

使用 Python 請求模塊下載並保存 PDF 文件

[英]Download and save PDF file with Python requests module

我正在嘗試從網站下載 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)
   ...: 

我知道這是某種編解碼器問題,但我似乎無法讓它工作。

在這種情況下你應該使用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將輸出作為字節對象返回,在下載二進制文件時使用它。 如 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 ,則 requests 將下載該文件的前2000個字節,將它們寫入文件,並一次又一次地執行此操作,直到完成為止。

所以這可以節省您的 RAM。 但在這種情況下,我更願意使用response.content ,因為你的文件很小。 如您所見,使用response.raw很復雜。


相關:

在 Python 3 中,我發現 pathlib 是執行此操作的最簡單方法。 Request 的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)

您可以使用 urllib:

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

請注意我是初學者。 如果我的解決方案有誤,請隨時更正和/或讓我知道。 我也可能學到新東西。

我的解決方案:

將 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...')

通常,這應該適用於 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

關於 Kevin answer 寫在文件夾tmp中,它應該是這樣的:

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

他忘了. 在地址之前,當然你的文件夾tmp應該已經創建了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM