문제

웹 서버에서 전체 디렉토리를 다운로드하고 있습니다.정상적으로 작동하지만 다운로드하기 전에 파일 크기를 확인하여 서버에서 업데이트되었는지 여부를 비교하는 방법을 알 수 없습니다.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()

@존:빠른 답변에 감사드립니다.작동하지만 웹 서버의 파일 크기가 다운로드한 파일의 파일 크기보다 약간 작습니다.

예:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

CR/LF 변환과 관련이 있습니까?

도움이 되었습니까?

해결책

나는 당신이 보고 있는 것을 재현했습니다:

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

다른 팁

반환된 urllib 객체 메서드 사용 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

이것은 사전이므로 파일 크기를 얻으려면 다음을 수행하십시오. urllibobject.info()['Content-Length']

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

(비교를 위해) 로컬 파일의 크기를 얻으려면 os.stat() 명령을 사용할 수 있습니다.

os.stat("/the/local/file.zip").st_size

파일 크기는 Content-Length 헤더로 전송됩니다.urllib를 사용하여 가져오는 방법은 다음과 같습니다.

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

또한 연결하려는 서버가 이를 지원하는 경우 다음을 살펴보세요. E태그 그리고 If-수정-이후 그리고 일치하지 않는 경우 헤더.

이를 사용하면 웹 서버의 캐싱 규칙을 활용하고 304 수정되지 않음 내용이 변경되지 않은 경우 상태 코드입니다.

Python3에서는:

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

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

요청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
...
Content-Length                          : 35588
FILE SIZE (MB)                          : 0.03 MB
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top