cURL - 如何仅在自上次获取以来页面发生更改时获取页面?

8
我有一个脚本,每天获取网页内容,我希望只在内容改变时才获取它,这样脚本运行速度更快,使用的流量也更少。
我的想法是首先获取头部并比较内容长度,如果不同则获取整个文档,但这不太精确,因为网站可能有动态部分,导致内容长度每次都不同。
是否有其他方法,比如使用某种DNS或其他方式?

1
网络服务器是否返回 Etag 值?(https://en.wikipedia.org/wiki/HTTP_ETag) - sowa
很遗憾,但是你说得对。 - Kref
3个回答

2

我寻找答案超过两天,没有人能给我一个通用的答案。

因此,我实现了etag和if-modified-since标头(正如Matt Raines和sowa在这里发布的),还为降低流量使用了像gzip这样的压缩。

此外,还有请求头范围,因此我可以像有人告诉我那样仅抓取页面的一部分,但我认为它只用于文件而不是网页。

感谢大家花费时间。


2

更新本地文件,仅当远程文件较新时

以下是想要检查远程文件是否比本地文件更新,并在是的情况下更新本地文件的答案:

    // $remotePath = 'http://blahblah.com/file.ext'; 
    // $localPath = '/usr/whatever/app/file.ext';

    $headers = get_headers( $remotePath , 1 );
    $remote_mod_date = strtotime( $headers['Last-Modified'] );
    $local_mod_date = filemtime( $localPath );

    if ( $local_mod_date >= $remote_mod_date ) {
        // Local version up to date 
    } else {
        // Remote file is newer
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $remotePath);
        // other options here, eg: curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            // handle error : curl_error($ch) 
        }

        curl_close ($ch);

        if ( $result ) {
            // Update local file with remote file contents
            file_put_contents( $localPath, $result );
        } 
    }

感谢这里的问题的提问者以及这个答案
创建此工具是为了解决自动OIDC CA证书更新(此处, 还有这个)。

这个解决方案对我很有效,谢谢。我用它来从yr.no api检索天气数据。 - Terje Nesthus

0

curl_setopt($curl, CURL_HTTPHEADER, ["If-Modified-Since: 2016-04-30 21:00:00"]);这个代码行是否有效?我在一个上个月修改过的资源上得到了304 Not Modified的响应。


这仅适用于静态HTML页面,如果是动态页面(如PHP、Perl、Python等),服务器将不会自动添加Last-Modified响应头,因此它将不返回304代码。 - Kref
不错,我大多数的PHP页面都返回Last-Modified头信息,但我明白这并非总是如此。但是,如果我正确理解了问题,那么它是“如何识别未更改的页面,这些页面没有报告Last-Modified或Etag,除了页面中已更改的部分之外?”因为这似乎是一个相当具有挑战性的问题 ;) - Matt Raines

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接