পাইথন অনুরোধ মডিউল সহ পিডিএফ ফাইল ডাউনলোড এবং সংরক্ষণ করুন


87

আমি একটি ওয়েবসাইট থেকে একটি পিডিএফ ফাইল ডাউনলোড এবং এটি ডিস্কে সংরক্ষণ করার চেষ্টা করছি। আমার প্রচেষ্টা হয় এনকোডিং ত্রুটির সাথে ব্যর্থ হয় বা ফাঁকা পিডিএফ-এর ফলাফল।

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আউটপুটটিকে স্ট্রিং অবজেক্ট হিসাবে ফিরিয়ে দিন, আপনি যখন কোনও পাঠ্য ফাইল ডাউনলোড করছেন তখন এটি ব্যবহার করুন । যেমন এইচটিএমএল ফাইল ইত্যাদি

এবং response.contentআউটপুটটিকে বাইটস অবজেক্ট হিসাবে ফিরিয়ে দিন, আপনি যখন বাইনারি ফাইল ডাউনলোড করেন তখন এটি ব্যবহার করুন । যেমন পিডিএফ ফাইল, অডিও ফাইল, চিত্র ইত্যাদি


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বাইটগুলি ডাউনলোড করবে , সেগুলি ফাইলে লিখবে এবং এটি শেষ না হওয়া পর্যন্ত বার বার এই কাজটি করবে।

সুতরাং এটি আপনার র‌্যাম সংরক্ষণ করতে পারে। তবে response.contentআপনার ফাইলটি ছোট হওয়ায় আমি এর পরিবর্তে ব্যবহার করতে চাই । আপনি দেখতে পারেন ব্যবহার response.rawজটিল।


সম্পর্কিত:


দুর্দান্ত, প্রতিক্রিয়া.আর সম্পর্কে অতিরিক্ত তথ্যের জন্য আপনাকে ধন্যবাদ।
জিম

23

পাইথন 3-তে, আমি পাথলিব এটি করার সহজতম উপায়। অনুরোধের প্রতিক্রিয়া । কনটেন্ট প্যাথলিবের লেখার_বাইটস সহ সুন্দরভাবে বিবাহ করে।

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)

4
এই পোস্ট করার জন্য আপনাকে ধন্যবাদ। মূল প্রশ্নটি পাইথন ২.7 ছিল তবে আমি এখন পাইথন ৩ ব্যবহার করেছি এবং আমি এখন প্যাথলিব লাইব্রেরি সম্পর্কে জানতাম না [সংস্করণ ৩.৪ এ নতুন] এবং এটি আমার বর্তমান প্রকল্পগুলিতে অন্তর্ভুক্ত করব।
জিম

এটি দেয় 544এবং ফাইলটি ভেঙে যায়, কোনও ধারণা?
আহ্বন

@ অহবোন, আপনার মানে কী?
ব্যবহারকারী 6481870

14

আপনি urllib ব্যবহার করতে পারেন:

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

4
এটি সেরা এক, টিবিএইচ।
ধাওয়াল সাভালিয়া

এই এক সেরা
রকটিম

4
urlretrieveঅনুরোধ শিরোনাম নির্ধারণের জন্য বিশ্বব্যাপী সেটিংসের উপর নির্ভর করে, কিছু ব্যবহারের ক্ষেত্রে এটি উপযুক্ত নয়।
মাইকেল ক্রেনশো

5

সাধারণত, এটি পাইথন 3 এ কাজ করা উচিত:

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

মনে রাখবেন urllib এবং urllib2 পাইথন 2 এর পরে সঠিকভাবে কাজ করে না।

যদি কিছু রহস্যজনক ক্ষেত্রে অনুরোধগুলি কাজ না করে (আমার সাথে ঘটেছিল) তবে আপনি ব্যবহার করার চেষ্টা করতে পারেন

wget.download(url)

সম্পর্কিত:

ওয়েবপৃষ্ঠায় সমস্ত পিডিএফ ফাইল সন্ধান এবং ডাউনলোড করার জন্য এখানে একটি শালীন ব্যাখ্যা / সমাধান দেওয়া হয়েছে:

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


2

আমি একটি শিক্ষানবিস দয়া করে নোট করুন। যদি আমার সমাধানটি ভুল হয় তবে দয়া করে নির্দ্বিধায় সংশোধন করুন এবং / অথবা আমাকে জানান। আমিও নতুন কিছু শিখতে পারি।

আমার সমাধান:

ডাউনলোডপথটি সেই অনুযায়ী পরিবর্তন করুন যেখানে আপনি নিজের ফাইলটি সংরক্ষণ করতে চান। আপনার ব্যবহারের জন্য নিখরচায় পথটি নির্দ্বিধায় ব্যবহার করুন

ডাউনলোডফাই.পি হিসাবে নীচে সংরক্ষণ করুন।

ব্যবহার: 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...')

পাভেল, আপনার উত্তরের জন্য আপনাকে ধন্যবাদ। আমি যখন প্রথম এই প্রশ্নটি পোস্ট করি তখন আমি পাইথন নবাগত ছিলাম। এখন আমি ভাষাটি খুব ভাল জানি know কমান্ড লাইন থেকে একটি ফাইল ডাউনলোড করতে পাইথন স্ক্রিপ্ট লেখার আপনার ব্যবহারের ক্ষেত্রে উইজেট বা কার্লের মতো ইউটিলিটিগুলি আবৃত করা যেতে পারে। এছাড়াও, পোস্ট হিসাবে আপনার ফাংশন ডাউনলোড ফাইল নিজেকে কল করে বলে মনে হচ্ছে। আপনি কোড দ্বিতীয় ব্লক ইন্ডেন্ট করতে চান? স্ট্যাকওভারফ্লোতে আপনি এটিকে আউট-ডেন্টিং করে সংশোধন করতে পারেন। পাইথনের আরগপারস লাইব্রেরিতে আপনার একবার নজর দেওয়া উচিত বলেও আমি পরামর্শ দিতে চাই। আপনি এটি দুর্দান্ত কমান্ড লাইনের ইউটিলিটিগুলি তৈরি করতে ব্যবহার করতে পারেন। এটি আপনার জন্য পরামিতিগুলির যত্ন নেবে।
জিম

আমি আপনার ফাইল প্রবন্ধ পরিচালনার জন্য প্রাসঙ্গিক পরিচালক (ওপেন ... ফাইল হিসাবে: ইত্যাদি) ব্যবহার করতে চাই। আপনার কোড খুব সুন্দরভাবে লেখা আছে। আপনি পাইথন শেখার জন্য একটি ভাল পথে। শুভকামনা!
জিম

4
উত্তরের জন্য ধন্যবাদ, @ জিম! আমি পোস্টটি সম্পাদনা করেছি, এবং সত্যই আমি "ইনডেন্টের উদ্দেশ্যে" ছিল না: ডি প্রোগ্রামটির মূল অংশ। আপনার পরামর্শের জন্য ধন্যবাদ! :)
হাঁসের লিঙ্গ

-4

কোনও ফোল্ডারে লিখতে কেভিন উত্তর সম্পর্কে tmp, এটি এমন হওয়া উচিত:

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

তিনি .ঠিকানার আগে ভুলে গিয়েছিলেন এবং অবশ্যই আপনার ফোল্ডারটি tmpইতিমধ্যে তৈরি করা উচিত ছিল


4
1- কেভিন লিখতে আইডিয়া নিয়ে আসেননি tmp, এটি ওপির প্রশ্নের মতো ছিল। 2- /tmpডিরেক্টরিটি ইউনিক্স সিস্টেমে tmp হয় /tmp, কোন অবস্থিত.
realUser404
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.