file_get_contents返回403禁止

时间:2010-12-28 11:46:37

标签: php curl

我正在尝试创建一个sitescraper。我是在我的本地机器上制作的,它在那里工作得很好。当我在我的服务器上执行相同的操作时,它显示403禁止错误。 我正在使用PHP Simple HTML DOM Parser。我在服务器上得到的错误是:

  

警告:   的file_get_contents(http://example.com/viewProperty.html?id=7715888)   [function.file-get-contents]:失败   打开流:HTTP请求失败!   HTTP / 1.1 403禁止进入   /home/scraping/simple_html_dom.php上   第40行

触发它的代码行是:

$url="http://www.example.com/viewProperty.html?id=".$id;

$html=file_get_html($url);

我检查了服务器上的php.ini,并且allow_url_fopen为On。可能的解决方案是使用curl,但我需要知道我哪里出错了。

13 个答案:

答案 0 :(得分:28)

我知道这是一个很老的线索,但想过分享一些想法。

如果您在访问网页时没有获得任何内容,则很可能它并不希望您能够获取内容。那么它如何识别脚本试图访问网页而不是人类?通常,它是发送到服务器的HTTP请求中的User-Agent标头。

因此,为了使网站认为访问网页的脚本也是 human ,您必须在请求期间更改User-Agent标头。如果您将User-Agent标头设置为某些常用Web浏览器使用的值,则大多数Web服务器可能会允许您的请求。

下面列出了浏览器使用的常用用户代理列表:

  • Chrome:'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'

  • Firefox:'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0'

  • 等...

$context = stream_context_create(
    array(
        "http" => array(
            "header" => "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
        )
    )
);

echo file_get_contents("www.google.com", false, $context);

这段代码伪造了用户代理并将请求发送到https://google.com

参考文献:

干杯!

答案 1 :(得分:16)

这不是您的脚本的问题,而是您请求的资源。 Web服务器返回“禁止”状态代码。

可能会阻止PHP脚本以防止抓取,或者如果您提出的请求太多,则会阻止您的IP。

您应该与远程服务器的管理员交谈。

答案 2 :(得分:5)

你可以在第35行及以上的解析器类中更改它。

function curl_get_contents($url)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

function file_get_html()
{
  $dom = new simple_html_dom;
  $args = func_get_args();
  $dom->load(call_user_func_array('curl_get_contents', $args), true);
  return $dom;
}

您是否尝试过其他网站?

答案 3 :(得分:4)

远程服务器似乎有某种类型的阻塞。可能是用户代理,如果是这种情况,您可以尝试使用curl模拟网络浏览器的用户代理,如下所示:

$url="http://www.example.com/viewProperty.html?id=".$id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$html = curl_exec($ch);
curl_close($ch);

答案 4 :(得分:4)

在simple_html_dom.php中写这个为我工作

function curl_get_contents($url)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
$html = curl_exec($ch);
  $data = curl_exec($ch);
  curl_close($ch);
  return $data;
}

function file_get_html($url, $use_include_path = false, $context=null, $offset = -1, $maxLen=-1, $lowercase = true, $forceTagsClosed=true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT, $defaultSpanText=DEFAULT_SPAN_TEXT)
{
    $dom = new simple_html_dom;
  $args = func_get_args();
  $dom->load(call_user_func_array('curl_get_contents', $args), true);
  return $dom;
    //$dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText);

}

答案 5 :(得分:4)

在添加了simple_html_dom.php后添加此内容

ini_set('user_agent', 'My-Application/2.5');

答案 6 :(得分:2)

我意识到这是一个老问题,但是......

使用php7在linux上设置我的本地沙箱并运行它。使用终端运行脚本,php为CLI调用php.ini。我发现“user_agent”选项已被注释掉了。我取消注释并添加了一个Mozilla用户代理,现在它可以工作。

答案 7 :(得分:2)

在服务器之间进行服务器调用时,基本上是PHP脚本调用。由于这个原因,许多远程服务器使用php脚本阻止了调用,从而避免了网站的复制。通过使脚本看起来像是来自主脚本,可以很容易地克服这一问题。您可以使用以下代码。

modle.ID

答案 8 :(得分:1)

您是否检查了文件的权限?我在我的文件上设置了777(显然是在localhost中),我解决了这个问题。

答案 9 :(得分:0)

我有同样的pb。我只是从谷歌控制台开发者激活Youtube API ...它有效(不再禁止: - )

我不知道主题是否贬值,我想只想分享这个想法 祝福

答案 10 :(得分:0)

在我的情况下,服务器通过其.htaccess配置拒绝了HTTP 1.0协议。似乎file_get_contents使用的是HTTP 1.0版本。

答案 11 :(得分:0)

使用以下代码: 如果您使用-> file_get_contents

$context  = stream_context_create(
  array(
    "http" => array(
      "header" => "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
    )
));

========= 如果您使用curl,

curl_setopt($curl, CURLOPT_USERAGENT,'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36');

答案 12 :(得分:0)

您还可能需要在扩展程序中添加一些其他信息,以使该网站相信请求是来自人类的。这样做是从浏览器进入网站,然后复制在http请求中发送的所有其他信息。

// file1.js

const thisFunc = require('./file2');
const foo = "bar";

const newPromise = new Promise((resolve, reject) => {
   thisFunc
       .asyncFunction() // <-- I want to pass foo here
       .then(...)
}