Python中如何通过文件下载链接判断文件是否已更新?

别的公司每天不定时的会给我们数据,我们有一个定时系统检测文件数据是否更新,如果更新就下载。但有一个公司给我们的是 http 的文件下载链接,不知道如何在线上检测是否更新。之前的做法是下载下来和之前的作比较,有什么方法在下载钱就得知文件信息么? ps:刚刚实习,好多不懂的地方,请指教。


Python中如何通过文件下载链接判断文件是否已更新?
15 回复

让对方在下载链接带一个哈希值参数


import requests
import hashlib
from datetime import datetime

def check_file_update(url, local_file_path=None, previous_hash=None):
    """
    检查远程文件是否更新
    
    参数:
        url: 文件下载链接
        local_file_path: 本地文件路径(可选)
        previous_hash: 之前保存的文件哈希值(可选)
    
    返回:
        dict: 包含更新状态和文件信息的字典
    """
    try:
        # 获取远程文件信息
        response = requests.head(url, timeout=10)
        response.raise_for_status()
        
        # 获取HTTP头信息
        headers = response.headers
        remote_size = headers.get('Content-Length')
        last_modified = headers.get('Last-Modified')
        etag = headers.get('ETag')
        
        # 如果有本地文件,计算哈希值比较
        current_hash = None
        if local_file_path:
            try:
                with open(local_file_path, 'rb') as f:
                    current_hash = hashlib.md5(f.read()).hexdigest()
            except FileNotFoundError:
                current_hash = None
        
        # 获取远程文件内容计算哈希(需要GET请求)
        if previous_hash or (local_file_path and current_hash):
            content_response = requests.get(url, timeout=30)
            content_response.raise_for_status()
            remote_hash = hashlib.md5(content_response.content).hexdigest()
        else:
            remote_hash = None
        
        # 判断是否更新
        is_updated = False
        if previous_hash and remote_hash:
            is_updated = remote_hash != previous_hash
        elif local_file_path and current_hash and remote_hash:
            is_updated = remote_hash != current_hash
        elif last_modified:
            # 如果没有哈希值,使用最后修改时间
            # 这里需要你保存之前的最后修改时间进行比较
            pass
        
        return {
            'is_updated': is_updated,
            'file_size': int(remote_size) if remote_size else None,
            'last_modified': last_modified,
            'etag': etag,
            'remote_hash': remote_hash,
            'current_hash': current_hash
        }
        
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None

# 使用示例
if __name__ == "__main__":
    # 示例URL
    test_url = "https://example.com/file.zip"
    
    # 方法1: 使用本地文件路径比较
    result = check_file_update(test_url, local_file_path="local_file.zip")
    print(f"通过本地文件比较: {result}")
    
    # 方法2: 使用之前保存的哈希值比较
    previous_hash = "abc123def456"  # 这是你之前保存的哈希值
    result = check_file_update(test_url, previous_hash=previous_hash)
    print(f"通过哈希值比较: {result}")
    
    # 方法3: 只检查文件信息(不下载完整文件)
    result = check_file_update(test_url)
    print(f"文件信息: {result}")

核心就三点:比较哈希值最可靠,检查Last-Modified时间戳,或者用ETag标识。哈希值对比是最准确的方法,特别是对于大文件可以避免重复下载。

顶楼上,带哈希值,如果下载链接每次都变可以比对链接地址,或者和对方商量一下,他们那边更新后通过接口给你一个消息,你方接受到消息则认为文件更新,然后进行下载;等等的,方法很多的

head 可以拿到文件大小,可以做简单的判断

last-modified

阁下正解,十分感谢

etag+1 https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=zh-cn#etag

不过也需要服务器端正确实现才可以,如果没实现,还是让他们在链接加一个 hash 参数简单

能让对方改的话我就让他们利用 ftp 或 sftp 了,沟通十分艰难。

last-modified、etag、Content-Length

都可以,简单、高效

最低成本的是使用 If-Modified-Since,给 If-Modified-Since 设置一个时间,源服务器会比对时间,当资源的更新时间大于 If-Modified-Since 的值时,返回 200 状态码,否则就是 304。

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/If-Modified-Since

让对方每次更新都提供文件的 MD5 值,判断值是否相同

最后修改时间呀~

第一次听说 etag,学习了。感谢!

学到了学到了

回到顶部