【问题标题】:xml download - blockedxml 下载 - 被阻止
【发布时间】:2013-04-16 21:15:05
【问题描述】:

我正在尝试从一个波兰网站下载 xml 文件。第一天它可以工作,但后来我可以将此文件下载到我的服务器(但我可以在我的计算机上打开并下载它)。在我的服务器上应该有 xml 内容的文件中是 html 内容,告诉我我已被阻止。

我试图从我想从中获取 xml 的网站与网站管理员联系,他告诉我我没有被 IP 地址阻止。所以问题是我应该在标题中发送什么或下载这个文件?

我下载 xml 文件的代码如下,这是我要下载的 xml:http://www.polskatimes.pl/rss/fakty_kraj.xml

$headers[]  = "User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
$headers[]  = "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$headers[]  = "Accept-Language:pl-PL,pl;q=0.8";
$headers[]  = "Accept-Encoding:gzip,deflate,sdch";
$headers[]  = "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7";
$headers[]  = "Keep-Alive:115";
$headers[]  = "Connection:keep-alive";
$headers[]  = "Cache-Control:max-age=0";

$xml_data = file_get_contents($xml,false,stream_context_create(
    array("http" => array('header' => $headers)))); // your file is in the string "$xml" now.
file_put_contents($xml_md5, $xml_data); // now your xml file is saved.

以详细模式(-v)请求 URL:

* About to connect() to www.polskatimes.pl port 80 (#0)
*   Trying 195.8.99.38... connected
* Connectede to www.polskatimes.pl (195.8.99.38) port 80 (#0)
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
> Host: www.polskatimes.pl
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Thu, 18 Apr 2013 10:40:15 GMT
< Content-Type: text/html; charset=utf8
< Transfer-Encoding: chunked
< Connection: close
< Vary: Accept-Encoding
< Expires: Thu, 18 Apr 2013 10:40:15 GMT
< Cache-Control: max-age=0
(html page with message that I am temporary blocked)
* Closing connection #0

【问题讨论】:

  • 如果你自己点击 url 会发生什么?还是来自(比如说)服务器命令行上的 wget?你确定你需要所有这些标头,而普通的$xml = file_get_contents($url) 也不能正常工作吗?
  • 当我使用 wget 或将 url 输入到 lynx 时也会发生同样的情况,所以问题是从服务器获取文件。在乞求时,我并没有使用所有这些标题,但是当这个问题开始时,我在这里寻找答案,我发现问题可能出在标题上,但对它们也不起作用。
  • 并且相同的 url 在另一台机器上可以正常工作吗?服务器和该站点之间的任何代理/过滤器可能会拒绝请求?或者,如果过滤不是通过 IP 进行的,您是否必须以某种方式登录该站点才能获取数据?
  • 是的,它在我的工作站上运行良好。服务器和该站点之间没有任何代理/过滤器。我没有从这个网站登录的权限。

标签: php xml file-get-contents


【解决方案1】:

要检查幕后发生的事情(以及您实际需要或不需要哪些标头),您需要进行一些分析。这没什么神奇的,您可以使用名为 curl 的软件在命令行上完成。它适用于许多(甚至所有?)计算机平台。

第一步通常是以详细模式请求 URL (-v):

$ curl -v http://www.polskatimes.pl/rss/fakty_kraj.xml
* About to connect() to www.polskatimes.pl port 80 (#0)
*   Trying 195.8.99.38... connected
* Connected to www.polskatimes.pl (195.8.99.38) port 80 (#0)
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.polskatimes.pl
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Wed, 17 Apr 2013 17:39:51 GMT
< Server: Apache
< Set-Cookie: sprawdz_cookie=1; expires=Thu, 17-Apr-2014 17:39:51 GMT
< Location: http://www.polskatimes.pl/rss/fakty_kraj.xml?cookie=1
< Vary: Accept-Encoding
< Content-Length: 0
< Connection: close
< Content-Type: text/html; charset=iso-8859-2
<
* Closing connection #0

这显示了请求(以 > 为前缀)和响应(以 为前缀)标头和响应正文(在这种情况下为空)。如您所见,状态为 302 Found,这意味着 3xx 是重定向,并且位置标头告诉您要去哪里:

Location: http://www.polskatimes.pl/rss/fakty_kraj.xml?cookie=1

正如查询参数所暗示的,这是一个 cookie 检查。 cookie 本身也已设置:

Set-Cookie: sprawdz_cookie=1; expires=Thu, 17-Apr-2014 17:39:51 GMT

所以在下一步中,我们将重播最后一个命令,但这次设置 cookie,这可以通过 -b 参数完成:

$ curl -v -b prawdz_cookie=1 http://www.polskatimes.pl/rss/fakty_kraj.xml
* About to connect() to www.polskatimes.pl port 80 (#0)
*   Trying 195.8.99.38... connected
* Connected to www.polskatimes.pl (195.8.99.38) port 80 (#0)
> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.polskatimes.pl
> Accept: */*
> Cookie: prawdz_cookie=1
>
< HTTP/1.1 200 OK
< Date: Wed, 17 Apr 2013 17:43:52 GMT
< Server: Apache
< Set-Cookie: sesja_gratka=e38fa0eb93705c8de7ae906198494439; expires=Wed, 24-Apr-2013 17:43:52 GMT; path=/; domain=polskatimes.pl
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Vary: Accept-Encoding
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/xml; charset=utf-8
<
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title><![CDATA[Fakty - Kraj]]></title>
    <link>http://www.polskatimes.pl/fakty/kraj/</link>
    <atom:link href="http://www.polskatimes.pl/rss/fakty_kraj.xml" rel="self" type="application/rss+xml"/>
    <description><![CDATA[Materiały z działu Kraj]]></description>
... (cutted)

所以这立即成功。现在真正好的部分:您知道您需要为请求设置 cookie 并且 curl 已经向您显示了它使用的所有标头:

> GET /rss/fakty_kraj.xml HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: www.polskatimes.pl
> Accept: */*
> Cookie: prawdz_cookie=1

file_get_contents、第一行以及 Host:Accept: 行中的大多数您不需要关心。

User-Agent: 标头看起来并没有真正发挥作用,因为 curl 被接受。

所以剩下的就是 Cookie: 标头。让我们在 PHP 中尝试:

$ php -r "echo file_get_contents('http://www.polskatimes.pl/rss/fakty_kraj.xml', null, 
stream_context_create(['http'=>['header'=>['Cookie: prawdz_cookie=1']]]));"
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title><![CDATA[Fakty - Kraj]]></title>
    <link>http://www.polskatimes.pl/fakty/kraj/</link>
    <atom:link href="http://www.polskatimes.pl/rss/fakty_kraj.xml" rel="self" 
    type="application/rss+xml"/>
...  (cutted)

这是直接测试只需要 Set-Cookie: prawdz_cookie=1 标头。

【讨论】:

  • 感谢 hakre,因为这看起来非常好,但不幸的是它对我没有帮助,因为我的服务器仍然无法下载此文件
  • 那么你在你的 shell 中用 curl 得到了什么样的响应?您应该逐步按照我在答案中概述的内容进行操作,以便您开始了解幕后发生的事情。我还将所有输出都放在了答案中,这样您就可以比较它在此处的表现以及它在您的计算机上的表现。
  • 我在我的服务器上添加了来自 curl 的问题回复。奇怪的是,在您的响应中,您有状态 302 和服务器 Apache,而我的状态是 200 和服务器 nginx,并且仍然是 html 页面,其中包含我暂时被阻止的信息。
  • 是的,好吧,那你就被屏蔽了。如您所见,请求本身与我的并没有太大不同,所以我会说您的 IP 被阻止。同样有趣的是,您的响应来自 Nginx,而我的响应来自 Apache。临时阻止可能是暗示触发了某些事情,因此阻止只是临时的。另外我想知道为什么他们为阻止消息设置了 200 OK。显然不是内容。仅从请求就没有什么可说的了。如果您愿意,我可以尝试在我这边挑起这件事,但这对您也无济于事。也许你用得太频繁了?
  • 我经常使用它(每 10 分钟一次),因为我想检查此 XML 中是否有新内容,如果有,则插入我的数据库。所以我经常使用它,但从大约 2 周开始我没有使用它,我仍然被阻止。更何况这个网站的人告诉我我的IP地址没有被屏蔽。
猜你喜欢
  • 1970-01-01
  • 2010-09-17
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多