52

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()

@Jon: 素早い回答ありがとうございます。動作しますが、Web サーバー上のファイルサイズは、ダウンロードしたファイルのファイルサイズよりわずかに小さくなります。

例:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

CR/LF 変換と何か関係がありますか?

4

9 に答える 9

36

私はあなたが見ているものを再現しました:

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 は正しいサイズを返していませんか?


編集:OK、私は問題が何であるかを理解しました:

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")
于 2008-08-08T14:21:51.107 に答える
27

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

これはdictなので、ファイルのサイズを取得するには、次のようにしますurllibobject.info()['Content-Length']

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

ローカル ファイルのサイズを取得するには (比較用)、os.stat() コマンドを使用できます。

os.stat("/the/local/file.zip").st_size
于 2008-08-08T13:47:26.373 に答える
11

GET の代わりに HEAD を使用するrequestsベースのソリューション (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
...
Content-Length                          : 35588
FILE SIZE (MB)                          : 0.03 MB
于 2016-12-04T10:21:43.087 に答える
7

ファイルのサイズは Content-Length ヘッダーとして送信されます。urllib で取得する方法は次のとおりです。

>>> site = urllib.urlopen("http://python.org")
>>> meta = site.info()
>>> print meta.getheaders("Content-Length")
['16535']
>>>
于 2008-08-08T13:41:43.043 に答える
6

また、接続先のサーバーがサポートしている場合は、EtagsIf-Modified-SinceおよびIf-None-Matchヘッダーを確認してください。

これらを使用すると、Web サーバーのキャッシュ ルールが利用され、コンテンツが変更されていない場合は304 Not Modifiedステータス コードが返されます。

于 2008-08-08T13:51:23.290 に答える