【问题标题】:Variables response from file_get_contents for 'https://en.wikipedia.org/wiki/Category:Upcoming_singles'来自“https://en.wikipedia.org/wiki/Category:Upcoming_singles”的 file_get_contents 的变量响应
【发布时间】:2011-10-06 22:50:10
【问题描述】:
file_get_contents('https://en.wikipedia.org/wiki/Category:Upcoming_singles');  

与使用 Chrome 网络浏览器访问同一地址(显示 4 个产品)返回不同的响应(2 个产品)。

经检查,我怀疑这可能与

保存在解析器缓存键中...时间戳...

在返回的 html 中。当我使用file_get_contents()时,时间戳更旧

关于如何使用file_get_contents() 获取最新信息的任何想法?

谢谢!

【问题讨论】:

  • 你的意思是file_get_contents
  • 是的,我的意思是 file_get_contents(),谢谢!

标签: php caching screen-scraping wikipedia


【解决方案1】:

假设file_get_contents 正在发出http 请求,最好检查指定的用户代理。

我听说使用某些用户代理获取数据时出现问题。看看this question

您可以使用流上下文指定其他选项(包括用户代理):

<?php
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: foo=bar\r\n"
  )
);

$context = stream_context_create($opts);

// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);

看看file_get_contents docs

另外,正如 Jack 所说,cURL 是一个更好的选择。

编辑:

你误会了。您需要添加的是不同的用户代理。例如,使用 mozilla firefox 的用户代理可以获得 4 个结果:

<?php

    $opts = array(
      'http'=>array(
        'method'=>"GET",
        'header'=>"Accept-language: en\r\n" .
                  "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; es-AR; rv:1.9.2.23) Gecko/20110921 Ubuntu/10.10 (maverick) Firefox/3.6.23"
      )
    );

    $context = stream_context_create($opts);

    // Open the file using the HTTP headers set above
    $file = file_get_contents('http://en.wikipedia.org/wiki/Category:Upcoming_singles', false, $context);
    print $file;

但是,我认为这不“合法”,因此作弊是不好的。我认为维基百科必须提供任何其他用户代理来从外部应用程序获取其数据。

【讨论】:

  • 用户选项已设置。并且上下文是这样设置的, $opts = array('http' => array('header' => 'Cache-Control: no-cache', ) );它仍然给我同样的问题。明天我会尝试 cURL 并让你知道。谢谢!
  • 我尝试将用户代理设置为“Mozilla/5.0”,是的,我得到了 4 个结果,就像我使用浏览器一样。将其重置为旧用户代理“scraper”,现在也返回 4 个结果。它解决了我的问题,但我想知道为什么。非常感谢。
  • 一定是因为某种缓存。维基百科可以为某些类型的代理缓存静态文件,优先考虑浏览器。无论如何,我建议你问他们,或者阅读一下。
  • 我怀疑 User-Agent 标头是一个红鲱鱼——它应该对结果产生的唯一影响是某些用户代理被维基百科禁止并且会收到 HTTP 403 Forbidden 响应。既然你确实得到了正常的回应,那可能不是那样(但无论如何请看我和 Krinkle 的回应)。我的猜测是,这只是临时缓存陈旧的随机案例。
【解决方案2】:

无论如何,您确实应该使用MediaWiki API,而不是尝试从人类可读的类别页面中抓取信息。例如,try this query 使用 list=categorymembers

一些注意事项:

  • 选择合适的results format(对于PHP,可能是format=php)。
  • 默认限制是每个查询 10 个结果,但您可以使用 cmlimit=max 将其增加到 500 个。之后,您需要使用query continuation mechanism

您还可以使用现有的MediaWiki API client libraries 之一为您处理这些和其他小细节。

最后,请善待维基媒体服务器:不要同时发送多个查询,如果您很快会再次需要它们,请将结果缓存在本地。在 User-Agent 标头中包含您的联系信息(URL 或电子邮件地址)是个好主意,这样如果您的代码导致服务器负载过大,维基媒体的系统管理员可以轻松地与您联系。

【讨论】:

    【解决方案3】:

    根据Wikimedia User-Agent policy,要求所有请求都标识自己。我强烈建议不要伪造浏览器用户代理。没有必要。

    数以百万计的机器一直在访问维基百科和其他维基媒体基金会项目。只要确定你自己,你的剧本,这并不难!

    // Identify your bot, script, or company.
    // E.g. Link to a website, or provide an e-mail address.
    ini_set( 'user_agent', 'MyBot/1.0; John Doe (contact: info@example.og)' );
    
    // Open the file using the HTTP headers set above
    $contents = file_get_contents( 'http://en.wikipedia.org/wiki/Sandbox' );
    echo $contents;
    

    【讨论】:

      【解决方案4】:

      尝试使用 cURL 并设置标头来获取最新信息,而不是缓存(抱歉,我不记得要设置的确切标头)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-17
        • 2011-04-08
        • 2019-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-22
        相关资源
        最近更新 更多