Почему эта функция, использующая CURL, работает для одних URL-адресов, но не для других? - PullRequest
4 голосов
/ 16 февраля 2009

Я пишу сайт на PHP, который собирает данные с других сайтов. У меня есть функция returnPageSource, которая принимает URL-адрес и возвращает HTML-код этого URL-адреса в виде строки.

function returnPageSource($url){
    $ch = curl_init();
    $timeout = 5;   // set to zero for no timeout       

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     // means the page is returned
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOUT_CONNECTTIMEOUT, $timeout); // how long to wait to connect
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);     // follow redirects
    //curl_setopt($ch, CURLOPT_HEADER, False);          // only request body

    $fileContents = curl_exec($ch); // $fileContents contains the html source of the required website
    curl_close($ch);

    return $fileContents;
}

Это прекрасно работает для некоторых веб-сайтов, которые мне нужны, например, http://atensembl.arabidopsis.info/Arabidopsis_thaliana_TAIR/unisearch?species=Arabidopsis_thaliana_TAIR;idx=;q=At5g02310, но не для других, как http://www.bar.utoronto.ca/efp/cgi-bin/efpWeb.cgi?dataSource=Chemical&modeInput=Absolute&primaryGene=At5g02310&orthoListOn=0. Кто-нибудь знает, почему?

Обновление

Спасибо за ответы. Я изменил свой useragent, чтобы он был таким же, как мой браузер (Firefox 3, который может нормально обращаться к сайтам), изменил тайм-аут на 0, и я все еще не могу подключиться, но я могу получить некоторые сообщения об ошибках. curl_error () выдает мне ошибку «не удалось подключиться к хосту» и curl_getinfo ($ ch, CURLINFO_HTTP_CODE); возвращает HTTP-код 0 ... ни один из которых не очень полезен. Я также пробовал curl_setopt ($ ch, CURLOPT_VERBOSE, 1); но это ничего не отображало. У кого-нибудь есть другие идеи?

Окончательное обновление

Я только что понял, что не объяснил, в чем дело - мне просто нужно было ввести настройки прокси-сервера для моего университета (я использую университетский сервер). После этого все работало нормально!

Ответы [ 3 ]

6 голосов
/ 16 февраля 2009

Вы должны использовать curl_error(), чтобы проверить, какая ошибка произошла (если есть)

1 голос
/ 16 февраля 2009

Две вещи для рассмотрения.

Первое, вы установили тайм-аут на низкий уровень. На этих сайтах запрос может занимать более 5 секунд.

Во-вторых, рассматриваемые сайты могут намеренно блокировать ваш запрос. У них есть правило, блокирующее запросы, приходящие от curl, или они могли заметить подозрительную активность (либо просмотр вашего экрана, либо чье-либо злоупотребление сетью), исходящую с вашего IP-адреса, и блокируют / регулируют запросы.

1 голос
/ 16 февраля 2009

Полагаю, вы пытались установить время ожидания на 0.

Какие коды статуса HTTP возвращают эти сайты? Проверьте curl_getinfo($ch, CURLINFO_HTTP_CODE);.

Еще кое-что можно попробовать подделать заголовком User-Agent, возможно, с помощью заголовка вашего браузера, поскольку вы знаете, что он работает для доступа к этим страницам. Возможно, они просто пытаются остановить доступ ботов к странице.

Исследование заголовков и http-кодов должно дать вам немного больше информации.

Edit:

Я посмотрел на это немного больше. Во-первых, у вас есть опечатка для времени ожидания соединения - должно быть CURLOPT_CONNECTTIMEOUT.

В любом случае, я запустил этот скрипт (ниже), который вернул то, что вы ищете (я думаю). Проверьте, что отличается между ним и вашим. Я использую PHP 5.2.8, если это поможет.

<?php

$addresses = array(
    'http://atensembl.arabidopsis.info/Arabidopsis_thaliana_TAIR/unisearch?species=Arabidopsis_thaliana_TAIR;idx=;q=At5g02310',
    'http://www.bar.utoronto.ca/efp/cgi-bin/efpWeb.cgi?dataSource=Chemical&modeInput=Absolute&primaryGene=At5g02310&orthoListOn=0'
);

foreach ($addresses as $address) {
    echo "Address: http://www.bar.utoronto.ca/efp/cgi-bin/efpWeb.cgi?dataSource=Chemical&modeInput=Absolute&primaryGene=At5g02310&orthoListOn=0\n";
    // This box doesn't have http registered as a transport layer - pfft
    //var_dump(fsockopen($address, 80));

    $ch = curl_init($address);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);

    $fc = curl_exec($ch);

    echo "Info: " . print_r(curl_getinfo($ch), true) . "\n";

    echo "$fc\n";

    curl_close($ch);
}

Что возвращает следующее (TL; DR: мой cURL может нормально читать страницы):

C:\Users\Ross>php -e D:\sandbox\curl.php

Address: http://www.bar.utoronto.ca/efp/cgi-bin/efpWeb.cgi?dataSource=Chemical&modeInput=Absolute&primaryGene=At5g02310&orthoListOn=0

Info: Array
(
    [url] => http://atensembl.arabidopsis.info/Arabidopsis_thaliana_TAIR/unisearch?species=Arabidopsis_thaliana_TAIR;idx=;q=At5g02310
    [content_type] => text/html; charset=ISO-8859-1
    [http_code] => 200
    [header_size] => 168
    [request_size] => 151
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.654
    [namelookup_time] => 0.004
    [connect_time] => 0.044
    [pretransfer_time] => 0.044
    [size_upload] => 0
    [size_download] => 7531
    [speed_download] => 11515
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 0.57
    [redirect_time] => 0
)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb"  lang="en-gb">
<head>
  <title>AtEnsembl release 49: Arabidopsis thaliana TAIR EnsEMBL UniSearch results</title>
  <style type="text/css" media="all">
    @import url(/css/ensembl.css);
    @import url(/css/content.css);
  </style>
  <style type="text/css" media="print">
    @import url(/css/printer-styles.css);
  </style>
  <style type="text/css" media="screen">
    @import url(/css/screen-styles.css);
  </style>
  <script type="text/javascript" src="/js/protopacked.js"></script>
  <script type="text/javascript" src="/js/core42.js"></script>
  <!-- Snipped for freedom - lots of lines -->
</body>
</html>

Address: http://www.bar.utoronto.ca/efp/cgi-bin/efpWeb.cgi?dataSource=Chemical&modeInput=Absolute&primaryGene=At5g02310&orthoListOn=0

Info: Array
(
    [url] => http://www.bar.utoronto.ca/efp/cgi-bin/efpWeb.cgi?dataSource=Chemical&modeInput=Absolute&primaryGene=At5g02310&orthoListOn=0
    [content_type] => text/html; charset=UTF-8
    [http_code] => 200
    [header_size] => 146
    [request_size] => 155
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 2.695
    [namelookup_time] => 0.004
    [connect_time] => 0.131
    [pretransfer_time] => 0.131
    [size_upload] => 0
    [size_download] => 14156
    [speed_download] => 5252
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => 0
    [starttransfer_time] => 2.306
    [redirect_time] => 0
)

<html>
<head>
  <title>Arabidopsis eFP Browser</title>
  <link rel="stylesheet" type="text/css" href="efp.css"/>
  <link rel="stylesheet" type="text/css" href="domcollapse.css"/>
  <script type="text/javascript" src="efp.js"></script>
  <script type="text/javascript" src="domcollapse.js"></script>
</head>
<body>
<!-- SANITY SNIP -->
</body>
</html>

Так что это значит? Не совсем уверен. Я сомневаюсь, что они специально блокируют вас (поскольку вы можете получить доступ к странице, если вы не запускаете этот скрипт на веб-сервере). Попробуйте запустить мой код выше - если это работает, попробуйте закомментировать части вашего кода, чтобы увидеть, что отличается (и, возможно, вызывает остановку). И какую версию PHP вы используете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...