XML и Яндекс

Delph

Новичок
XML и Яндекс

Имею следующий код:

PHP:
$host = "xmlsearch.yandex.ru"; 
$uri = "/xmlsearch/"; 
$body = '<?xml version="1.0" encoding="utf-8"?> 
<request>
    <query>Something</query> 
    <groupings>
<groupby attr="d" mode="deep" groups-on-page="20"  docs-in-group="1" />
</groupings>
</request>'; 

$request = "POST {$uri} HTTP/1.0\n"; 
$request .= "Host: {$host}\n"; 
$request .= "Content-Type: text/xml\n"; 
$request .= "Content-Length: " . strlen($body). "\n\n"; 
$request .= $body; 

$sock = pfsockopen($host, 80); 
fwrite($sock, $request); 

$response = ""; 
while (!feof($sock)) 
{ 
    $str = fgets($sock, 8192); 
    $response .= $str; 
} 

$simple=substr($response,strpos($response,'<yandexsearch version="1.0">')); 


$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
Далее разбираю массив $vals и отбираю нужные мне вещи (мне нужно вытащить все урлы).

Проблема в следующем:
Мне нужно выкачать из яндекса все урлы, а не первые 20. Если ставлю groups-on-page большее 20 выдает ошибку.
Если воспользоваться циклом, то работает все очень медленно (естественно).

Есть ли у кого-нибудь идеи как можно реализовать? (PHP 4)

-~{}~ 05.05.06 12:19:

Да, и еще во время выборки по каждому url происходит еще 2 соединения - проверка ТИЦ на Яндексе и PR на Google.
 

voituk

прозревший
Никак.
Согласно документации от Яндекс - за один запрос можно получить не более 20 результатов поиска.

Как вариант, если есть возможность, не выполнять подобные действия online, а производить во время минимальной нагрузки на сетевые каналы и сервер (например ночью)
 

Delph

Новичок
Тогда можно ли как то сократить время, которое затрачивается каждый раз на открытие сокета? Или один раз вообще открывать сокет?

-~{}~ 05.05.06 12:39:

То есть грубо говоря соединился с Яндексом, все оттуда нужное выкачал, потом разорвал соединение. Как-то можно это реализовать или все-равно придется несколько раз использовать fsockopen?
 

voituk

прозревший
Читай внимательнее HTTP-протокол
ключевые слова

Connection: Keep-Alive
 

Delph

Новичок
Прописал:
PHP:
$request .= "Keep-Alive: 300\r\n";
$request .= "Connection: keep-alive\r\n";
Вообще никак не повлияло. Надо ли еще прописывать в php.ini
KeepAlive On ?
 

voituk

прозревший
А какого эфекта ты ожидал?
Дописать указанные строки в приведенный выше код - не достаточно.
Нужно не разрывая соединения отправлять следующий запрос, получать ответ, и так покругу.

Вполне возможно что Yandex просто не поддерживает Keep-alive
 

Delph

Новичок
Насколько я понимаю, если я прописываю эти строки, и не использую fclose, то как раз соединение не разрывается. Или я не прав?

-~{}~ 05.05.06 16:24:

Яндекс упорно выдает следующие хедеры:
HTTP/1.1 200 OK
Date: Fri, 05 May 2006 12:21:42 GMT
Server: Apache/1.3.29 (Unix) mod_perl/1.29 mod_deflate/1.0.21 rus/PL30.19
Connection: close
Content-Type: text/xml

1) Если я добьюсь чтобы не закрывалось соединение строка Connection: close пропадет?
2) Можно ли на самом простом примере как-то проверить, поддерживает ли Яндекс Keep-alive?
 

voituk

прозревший
Код:
telnet ya.ru 80
Trying 213.180.204.8...
Connected to ya.ru.
Escape character is '^]'.
GET / HTTP/1.1
Host: ya.ru
Connection: keep-alive

HTTP/1.0 200 OK
Server: thttpd/2.25b 29dec2003
Content-Type: text/html; charset=windows-1251
Date: Fri, 05 May 2006 12:25:30 GMT
Last-Modified: Fri, 13 Jan 2006 11:32:56 GMT
Accept-Ranges: bytes
Content-Length: 2003
Age: 37
X-Cache: HIT from ua.rproxy.yandex.net
Connection: keep-alive
...
...

GET / HTTP/1.1
Host: ya.ru
...
...
Connection closed by foreign host.
Пробуй что-то аналогичное для сервера xmlsearch.yandex.ru
 

Delph

Новичок
telnet у меня почему-то не работает. Может я че-то туплю. [cmd->telnet->o ya.ru 80]
Пробовал опять же так:
PHP:
$fp = fsockopen("www.ya.ru", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)<br />\n";
} else {
   $out = "GET / HTTP/1.1\r\n";
   $out .= "Host: www.ya.ru\r\n";
   $out .= "Connection: Keep-Alive\r\n\r\n";

   fwrite($fp, $out);
   while (!feof($fp)) {
       echo fgets($fp, 128);
   }
   fclose($fp);
}
Выдает:
HTTP/1.1 200 OK
Server: thttpd/2.25b 29dec2003
Content-Type: text/html; charset=windows-1251
Date: Fri, 05 May 2006 12:42:00 GMT
Last-Modified: Fri, 13 Jan 2006 11:32:57 GMT
Accept-Ranges: bytes
Connection: close
Content-Length: 2003
 

voituk

прозревший
Попробуй "Connection: keep-alive" (именно маленькими буквами keep-alive)

Ещё может у меня работает а у тебя нет, потому что я коннектюсь к Украинской "версии" ya.ru (IP:213.180.204.8)
 

Delph

Новичок
Не, ниче не меняется. С телнетом я вроде справился. Насколько я понимаю все таки поддержка есть. Маленькими буквами тоже не выходит. А можешь у себя попробовать это:
PHP:
$fp = fsockopen("www.ya.ru", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)<br />\n";
} else {
   $out = "GET / HTTP/1.1\r\n";
   $out .= "Host: www.ya.ru\r\n";
   $out .= "Connection: keep-alive\r\n\r\n";

   fwrite($fp, $out);
   while (!feof($fp)) {
       echo fgets($fp, 128);
   }
   fclose($fp);
}
-~{}~ 05.05.06 17:23:

IP у меня такой же пингует

-~{}~ 05.05.06 17:28:

Проделал такое с разными доменами.
На некоторых все-таки Connection: Keep-Alive выдает.
Можно ли отсюда сделать вывод, что просто Яндекс это не поддерживает?
 

Delph

Новичок
Ответ из техподдержки яндекса если кому интересно:

Действительно keep-alive не поддерживается и запрашивать страницы нужно последовательно
 
Сверху