पायथन में डाउनलोड करने से पहले फ़ाइल का आकार प्राप्त करें

मैं एक वेब सर्वर से एक पूरी निर्देशिका डाउनलोड कर रहा हूँ। यह ठीक काम करता है, लेकिन मैं यह समझ नहीं सकता कि डाउनलोड करने से पहले फ़ाइल आकार कैसे प्राप्त करें, अगर यह सर्वर पर अपडेट किया गया था या नहीं। क्या ऐसा किया जा सकता है जैसे कि मैं एक FTP सर्वर से फ़ाइल डाउनलोड कर रहा था?

import urllib
import re

url = "http://www.someurl.com"

# Download the page locally
f = urllib.urlopen(url)
html = f.read()
f.close()

f = open ("temp.htm", "w")
f.write (html)
f.close()

# List only the .TXT / .ZIP files
fnames = re.findall('^.*

@ जोन: आपके त्वरित उत्तर के लिए धन्यवाद। यह काम करता है, लेकिन वेब सर्वर पर फाइलसाइज डाउनलोड की गई फाइल के फाइलसाइज से थोड़ा कम है।

उदाहरण:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

सीआर / एलएफ रूपांतरण के साथ इसका कोई संबंध नहीं है?

0
ro fr bn
आप सही हैं, लेखन के लिए स्थानीय फ़ाइल खोलते समय मैं "wb" का उपयोग नहीं कर रहा था। एक जादू की तरह काम करता है! धन्यवाद
जोड़ा लेखक PabloG, स्रोत
संभवतः। क्या आप इस पर diff चला सकते हैं और एक अंतर देख सकते हैं? क्या आप बाइनरी (.zip) फ़ाइलों में फ़ाइल आकार अंतर भी देखते हैं? संपादित करें: यह वह जगह है जहां इटैग जैसी चीजें आसान होती हैं। कुछ बदलाव होने पर सर्वर आपको बताएगा, इसलिए आपको इसे समझने के लिए पूरी फ़ाइल डाउनलोड करने की आवश्यकता नहीं है।
जोड़ा लेखक Jonathan Works, स्रोत

7 उत्तर

लौटा-urllib-object विधि info() का उपयोग करके, आप पुनर्प्राप्त दस्तावेज़ पर विभिन्न जानकारी प्राप्त कर सकते हैं। वर्तमान Google लोगो को पकड़ने का उदाहरण:

>>> import urllib
>>> d = urllib.urlopen("http://www.google.co.uk/logos/olympics08_opening.gif")
>>> print d.info()

Content-Type: image/gif
Last-Modified: Thu, 07 Aug 2008 16:20:19 GMT  
Expires: Sun, 17 Jan 2038 19:14:07 GMT 
Cache-Control: public 
Date: Fri, 08 Aug 2008 13:40:41 GMT 
Server: gws 
Content-Length: 20172 
Connection: Close

It's a dict, so to get the size of the file, you do urllibobject.info()['Content-Length']

print f.info()['Content-Length']

और स्थानीय फ़ाइल का आकार प्राप्त करने के लिए (तुलना के लिए), आप os.stat() कमांड का उपयोग कर सकते हैं:

os.stat("/the/local/file.zip").st_size
0
जोड़ा
जोड़ा लेखक dbr, स्रोत
मैं इस समाधान का उपयोग कर रहा हूं, हालांकि मैंने एक एज केस मारा है जहां कभी-कभी सामग्री-लंबाई शीर्षलेख परिभाषित नहीं किया जाता है। क्या कोई यह समझा सकता है कि इसे लगातार क्यों नहीं किया जाएगा?
जोड़ा लेखक wbeange, स्रोत

GET के बजाय HEAD का उपयोग करके एक अनुरोध -आधारित समाधान (HTTP हेडर प्रिंट करता है):

#!/usr/bin/python
# display size of a remote file without downloading

from __future__ import print_function
import sys
import requests

# number of bytes in a megabyte
MBFACTOR = float(1 << 20)

response = requests.head(sys.argv[1], allow_redirects=True)

print("\n".join([('{:<40}: {}'.format(k, v)) for k, v in response.headers.items()]))
size = response.headers.get('content-length', 0)
print('{:<40}: {:.2f} MB'.format('FILE SIZE', int(size) / MBFACTOR))

प्रयोग

  $ python filesize-remote-url.py https://httpbin.org/image/jpeg
...
सामग्री-लंबाई: 35588
फ़ाइल आकार (एमबी): 0.03 एमबी
 
0
जोड़ा

एक पायथन 3 (3.5 पर परीक्षण) दृष्टिकोण के लिए मैं अनुशंसा करता हूं:

with urlopen(file_url) as in_file, open(local_file_address, 'wb') as out_file:
    print(in_file.getheader('Content-Length'))
    out_file.write(response.read())
0
जोड़ा

फ़ाइल का आकार सामग्री-लंबाई शीर्षलेख के रूप में भेजा जाता है। यहां urllib के साथ इसे प्राप्त करने का तरीका बताया गया है:

>>> site = urllib.urlopen("http://python.org")
>>> meta = site.info()
>>> print meta.getheaders("Content-Length")
['16535']
>>>
0
जोड़ा

इसके अलावा यदि आप जिस सर्वर से कनेक्ट करने के लिए कनेक्ट कर रहे हैं, तो Etags और अगर संशोधित-चूंकि और अगर-कोई नहीं-मैच शीर्षलेख।

इनका उपयोग वेबसर्वर के कैशिंग नियमों का लाभ उठाएगा और एक 304 संशोधित नहीं किया गया स्थिति कोड वापस करेगा अगर सामग्री नहीं बदली है।

0
जोड़ा

मैंने जो कुछ देखा है उसे पुन: उत्पन्न किया है:

import urllib, os
link = "http://python.org"
print "opening url:", link
site = urllib.urlopen(link)
meta = site.info()
print "Content-Length:", meta.getheaders("Content-Length")[0]

f = open("out.txt", "r")
print "File on disk:",len(f.read())
f.close()


f = open("out.txt", "w")
f.write(site.read())
site.close()
f.close()

f = open("out.txt", "r")
print "File on disk after download:",len(f.read())
f.close()

print "os.stat().st_size returns:", os.stat("out.txt").st_size

आउटपुट यह:

opening url: http://python.org
Content-Length: 16535
File on disk: 16535
File on disk after download: 16535
os.stat().st_size returns: 16861

मुझसे यहां क्या गलत हो रहा है? Os.stat ()। St_size सही आकार को वापस नहीं कर रहा है?


संपादित करें: ठीक है, मुझे पता चला कि समस्या क्या थी:

import urllib, os
link = "http://python.org"
print "opening url:", link
site = urllib.urlopen(link)
meta = site.info()
print "Content-Length:", meta.getheaders("Content-Length")[0]

f = open("out.txt", "rb")
print "File on disk:",len(f.read())
f.close()


f = open("out.txt", "wb")
f.write(site.read())
site.close()
f.close()

f = open("out.txt", "rb")
print "File on disk after download:",len(f.read())
f.close()

print "os.stat().st_size returns:", os.stat("out.txt").st_size

यह आउटपुट:

$ python test.py
opening url: http://python.org
Content-Length: 16535
File on disk: 16535
File on disk after download: 16535
os.stat().st_size returns: 16535

सुनिश्चित करें कि आप बाइनरी पढ़ने / लिखने के लिए दोनों फाइलें खोल रहे हैं।

// open for binary write
open(filename, "wb")
// open for binary read
open(filename, "rb")
0
जोड़ा
जब आप site = urllib.urlopen (link) करते हैं तो आपने फ़ाइल डाउनलोड किया है, इसलिए यह बफर को डाउनलोड किए जाने से पहले अपने आकार को डाउनलोड करने से पहले आकार नहीं है, जहां से आप सामग्री-लंबाई को पुनर्प्राप्त कर रहे हैं
जोड़ा लेखक Ciasto piekarz, स्रोत
@Ciastopiekarz मुझे लगता है कि जब आप पढ़ने की कोशिश करते हैं() कि फ़ाइल वास्तव में बफर में डाउनलोड की जाती है यह उत्तर जांचें
जोड़ा लेखक CaptainDaVinci, स्रोत

पायथन 3 में:

>>> import urllib.request
>>> site = urllib.request.urlopen("http://python.org")
>>> print("FileSize: ", site.length)
0
जोड़ा
यह फ़ाइल डाउनलोड करता है!
जोड़ा लेखक Joseph Victor Zammit, स्रोत