在使用Python下载之前获取文件大小

Pab*_*loG 43 python urllib

我正在从Web服务器下载整个目录.它工作正常,但我无法想象如何在下载之前获取文件大小以进行比较,如果它在服务器上更新了.这可以像我从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('^.*<a href="(\w+(?:\.txt|.zip)?)".*$', html, re.MULTILINE)

for fname in fnames:
    print fname, "..."

    f = urllib.urlopen(url + "/" + fname)

    #### Here I want to check the filesize to download or not #### 
    file = f.read()
    f.close()

    f = open (fname, "w")
    f.write (file)
    f.close()
Run Code Online (Sandbox Code Playgroud)

@Jon:谢谢你的快速回答.它可以工作,但Web服务器上的文件大小略小于下载文件的文件大小.

例子:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121
Run Code Online (Sandbox Code Playgroud)

它与CR/LF转换有什么关系?

Jon*_*rks 26

我已经复制了你所看到的内容:

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
Run Code Online (Sandbox Code Playgroud)

输出:

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

我在这做错了什么?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
Run Code Online (Sandbox Code Playgroud)

这个输出:

$ 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
Run Code Online (Sandbox Code Playgroud)

确保打开两个文件以进行二进制读/写.

// open for binary write
open(filename, "wb")
// open for binary read
open(filename, "rb")
Run Code Online (Sandbox Code Playgroud)

  • 当你执行`site = urllib.urlopen(link)`时,你已经执行了文件下载,所以在下载其infact下载到缓冲区之前,它的大小不是你检索内容长度的地方 (5认同)
  • `urllib.urlopen` 在最新的 3.6 版本中不再有效 (3认同)

dbr*_*dbr 23

使用returned-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
Run Code Online (Sandbox Code Playgroud)

这是一个字典,所以为了获得文件的大小,你可以 urllibobject.info()['Content-Length']

print f.info()['Content-Length']
Run Code Online (Sandbox Code Playgroud)

要获取本地文件的大小(用于比较),可以使用os.stat()命令:

os.stat("/the/local/file.zip").st_size
Run Code Online (Sandbox Code Playgroud)


ccp*_*zza 9

请求为基础的溶液中使用HEAD代替GET(也打印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))
Run Code Online (Sandbox Code Playgroud)

用法

$ python filesize-remote-url.py https://httpbin.org/image/jpeg
...
Content-Length                          : 35588
FILE SIZE (MB)                          : 0.03 MB
Run Code Online (Sandbox Code Playgroud)


Jon*_*rks 7

文件大小作为Content-Length标头发送.以下是如何使用urllib获取它:

>>> site = urllib.urlopen("http://python.org")
>>> meta = site.info()
>>> print meta.getheaders("Content-Length")
['16535']
>>>
Run Code Online (Sandbox Code Playgroud)


小智 6

在Python3中:

>>> import urllib.request
>>> site = urllib.request.urlopen("http://python.org")
>>> print("FileSize: ", site.length)
Run Code Online (Sandbox Code Playgroud)

  • 这将下载文件! (12认同)

Jon*_*rks 5

此外,如果您要连接的服务器支持它,请查看Etags以及If-Modified-SinceIf-None-Match标头.

使用这些将利用Web服务器的缓存规则,如果内容未更改,将返回304 Not Modified状态代码.