【问题标题】:cURL - How to fetch page only if it has changed since last fetch?cURL - 仅当页面自上次获取后发生更改时如何获取页面?
【发布时间】:2016-08-25 10:37:34
【问题描述】:

我有一个每天抓取页面的脚本,我只想在内容发生变化时抓取它,这样脚本运行速度会更快,并且会使用更少的流量。

我的想法是首先获取标题并比较内容长度,以便如果它不同,我们会获取整个文档,但这并不太精确,因为网站可能具有动态部分,使得内容长度每次都不同。

还有其他方法吗,比如使用某种 DNS 或其他方式?

【问题讨论】:

标签: php caching curl web-scraping


【解决方案1】:

我找了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 );
            } 
        }
    

    感谢OP question here,还有this answer
    旨在解决自动 OIDC CA 证书续订问题(thisand this)。

    【讨论】:

    • 这个解决方案对我有用,谢谢。用于从 yr.no api 中检索天气数据。
    【解决方案3】:

    curl_setopt($curl, CURL_HTTPHEADER, ["If-Modified-Since: 2016-04-30 21:00:00"]); 有效吗?我收到了关于本月早些时候最后一次修改的资源的 304 Not Modified 响应。

    【讨论】:

    • 这仅适用于静态 html 页面,如果是动态(php、perl、python 等)页面,服务器将不会自动添加 Last-Modified 响应头,因此它不会返回 304代码
    • 不,很公平。我的大多数 PHP 页面都返回 Last-Modified 标头,但我很欣赏这不一定是这种情况。但是,如果我正确理解了这个问题,它是“如何识别没有更改的页面,除了 已经 更改的页面位之外,不报告 Last-Modified 或 Etag ?”因为这看起来很……一个挑战;)
    猜你喜欢
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    相关资源
    最近更新 更多