Как через CURL получить страницу яндекс выдачи

jabbaxatt

Добрый модератор
Регистрация
21 Янв 2009
Сообщения
902
Реакции
432
Как через CURL получить страницу яндекс выдачи?

Как не пробую - не получается, примеры с интернета тоже не работает.

Т.е. он всегда, сразу, 100% случаев выдаёт страницу с капчёй. При этом через браузер с того же компа - всё нормально ищется. Т.е. у меня проблема с эмуляцией запроса из браузера, а не с тем что мой IP забанен.

Есть у кого пример рабочего запроса на PHP + Curl, что-бы получить страницу выдачи яндекса по запросу?
 
Как через CURL получить страницу яндекс выдачи?

Как не пробую - не получается, примеры с интернета тоже не работает.

Т.е. он всегда, сразу, 100% случаев выдаёт страницу с капчёй. При этом через браузер с того же компа - всё нормально ищется. Т.е. у меня проблема с эмуляцией запроса из браузера, а не с тем что мой IP забанен.

Есть у кого пример рабочего запроса на PHP + Curl, что-бы получить страницу выдачи яндекса по запросу?
Можно API использовать Для просмотра ссылки Войди или Зарегистрируйся
 
Заголовки
PHP:
$header = array(
  'User-Agent: Opera/9.80 (Windows NT 6.1; WOW64; U; MRA 5.9 (build 4871); ru) Presto/2.10.289 Version/12.02',
  'Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1',
  'Accept-Language: ru-RU,ru;q=0.9,en;q=0.8',
  //'Accept-Encoding: gzip, deflate',
  'Connection: Keep-Alive',
);
$ch = curl_init('http://yandex.ru/yandsearch?text=1111111111');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
UP. Проверил без заголовков
PHP:
$ch = curl_init('http://yandex.ru/yandsearch?text=1111111111');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
Нормально отработало, без капчи. Видимо что то с вашим IP))
Но в любом случае. Делайте максимально естественней. Заголовки. Правильный реферер, cookie. Желательно прокси.
 
Последнее редактирование:
Я бы еще добавил что-то типа

PHP:
$agents = array(
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:7.0.1) Gecko/20100101 Firefox/7.0.1',
    'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100508 SeaMonkey/2.0.4',
    'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)',
    'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; da-dk) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1'
);

или

Код:
$agents = explode("\n", file_get_contents(https://raw.githubusercontent.com/cvandeplas/pystemon/master/user-agents.txt));

а потом так:
Код:
curl_setopt($ch,CURLOPT_USERAGENT,$agents[array_rand($agents)]);

Но не плохо бы и прокси прикрутить, это очень просто.
 
Еще немаловажный момент - частота запросов в интервал времени, при превышении происходит блокировка,
поэтому между запросами нужно ставить задержку.
Также яндекс насколько я понял сопоставляет сессии,
то есть если с одного IP идут запросы с разными куками - тоже возможен блок.
 
Да, можно привязать файлы куков к ip и user-agent.
Но лучше про тестить, часто оказывается что все на много проще :)
 
Всем спасибо. Но я уже отступил от своего плана и начал писать это на Delphi. Тамошний TWebBrowser позволяет нормально ходить по страничкам яндекса (имитируя некрофила со старым IE) и сохранять HTML код. Пару сотен страниц прогнал - капчи не выдаёт. Не знаю как поведёт себя на тысячах, но пока выглядит как более менее перспективный путь решения.

Оно конечно будет десктоп, а не сервер, но мне не критично.

Впрочем - если у кого ещё есть мысли или рабочий код - буду рад видеть их в этой теме.
Ибо на PHP у меня так и не получилось.
 
Последнее редактирование:
Всем спасибо. Но я уже отступил от своего плана и начал писать это на Delphi. Тамошний TWebBrowser позволяет нормально ходить по страничкам яндекса (имитируя некрофила со старым IE) и сохранять HTML код.
Попробуй selenium, работать с ним можно из любого популярного ЯП
 
Ну было бы время больше можно было бы доделать.
PHP:
<?php
define('DOMAIN','yandex.ua'); // Важено домен
define('SCHEME','http://');
define('NUMDOC','50');
define('SPRAVKA', 'dD0xNDI0NDQ5NjcwO2k9OTMuNzMuNTAuMjIzO3U9MTQyNDQ0OTY3MDE4NjcyNTk5MjtoPWZjODIyZTQxZTdiNmY3ZTI1ODRhMzk3ZjIwZWU2OWI2'); // Этот код можно получить если пройти капчу. Я удмаю можно сгенерить его самому. Это обычный base64
// t=UNIX_TIMESTAMP;i=ВАШ_IP;u=1424447588654410059;h=a9251aa16f61cdf3763cc5b1c28bff88
// Нужно только узнать как генерится u и хеш. Просто впадло ковырять. Этот код можно получить и долго рубить. Его так же можно получить если пройти капчу. По факту можно подключить антикапчу, эта капча вылазит редко если запрос подписан

$region = 143; // Киев, 213 Москоу
$query = 'парсер яндекса';
$url = SCHEME . DOMAIN . '/yandsearch?text='. urlencode($query) ."&lr={$region}&numdoc=" . NUMDOC;

function get_page($url)
{

    $ch = curl_init();

    $headers = array(
               'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4,uk;q=0.2',
               'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36',
               'Cookie: spravka=' . SPRAVKA . ';', // было бы больше времени, можно разобраться как получить автоматом.
            );

    $options = array(
        CURLOPT_TIMEOUT => 15,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_FOLLOWLOCATION => TRUE,
        CURLOPT_URL => $url,
        CURLOPT_HTTPHEADER => $headers,
    );
          
    curl_setopt_array($ch, $options);
    $data = curl_exec($ch);
  
    curl_close($ch);
    return $data;
}

$page = get_page($url);

libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->resolveExternals = false;
$dom->validateOnParse = false;
$dom->loadHTML($page);
$xpath = new DOMXpath($dom);

$serp_items = $xpath->query('//div[contains(@class, "serp-block") and not(contains(@class, "-adv"))]//*[contains(@class, "serp-item__wrap")]');

$links = array();

foreach ($serp_items as $k=>$item)
{
    $_tmp = array();
    $header_obj = $xpath->query('./h2', $item)->item(0);
  
    $_tmp['position'] = $k+1;
  
    $link_obj = $xpath->query('./a', $header_obj)->item(0);
    $_tmp['url'] = $link_obj->getAttribute('href');
    $_tmp['url_text'] = trim(preg_replace('/\s+/i', ' ', $link_obj->nodeValue));
  
    $links[] = $_tmp;
}

var_dump($links);
?>

Просто нет времени и особого желания)

Попробовал еще так

PHP:
<?php
   
define('DOMAIN','yandex.ua'); // Важено домен
define('SCHEME','http://');
define('NUMDOC','50');
define('SPRAVKA', ''); // Этот код можно получить если пройти капчу. Я удмаю можно сгенерить его самому. Это обычный base64
// t=UNIX_TIMESTAMP;i=ВАШ_IP;u=1424447588654410059;h=a9251aa16f61cdf3763cc5b1c28bff88
// Нужно только узнать как генерится u и хеш. Просто впадло ковырять. Этот код можно получить и долго рубить. Его так же можно получить если пройти капчу. По факту можно подключить антикапчу, эта капча вылазит редко если запрос подписан

$region = 143; // Киев, 213 Москоу
$query = 'парсер яндекса';
$url = SCHEME . DOMAIN . '/yandsearch?text='. urlencode($query) ."&lr={$region}&numdoc=" . NUMDOC . "&ncrnd=" . rand(100,999);

function get_page($url)
{

    $ch = curl_init();

    $headers = array(
                'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4,uk;q=0.2',
                'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36',
//                 'Cookie: spravka=' . SPRAVKA . ';', // было бы больше времени, можно разобраться как получить автоматом.
            );

    $options = array(
        CURLOPT_TIMEOUT => 15,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_FOLLOWLOCATION => TRUE,
        CURLOPT_URL => $url,
        CURLOPT_HTTPHEADER => $headers,
    );
           
    curl_setopt_array($ch, $options);
    $data = curl_exec($ch);
   
    curl_close($ch);
    return $data;
}

$page = get_page($url);

libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->resolveExternals = false;
$dom->validateOnParse = false;
$dom->loadHTML($page);
$xpath = new DOMXpath($dom);

$serp_items = $xpath->query('//div[contains(@class, "serp-block") and not(contains(@class, "-adv"))]//*[contains(@class, "serp-item__wrap")]');

$links = array();

foreach ($serp_items as $k=>$item)
{
    $_tmp = array();
    $header_obj = $xpath->query('./h2', $item)->item(0);
   
    $_tmp['position'] = $k+1;
   
    $link_obj = $xpath->query('./a', $header_obj)->item(0);
    $_tmp['url'] = $link_obj->getAttribute('href');
    $_tmp['url_text'] = trim(preg_replace('/\s+/i', ' ', $link_obj->nodeValue));
   
    $links[] = $_tmp;
}

var_dump($links);

вроде работает. В общем нужно разбираться, может когда-то будет такая задача то выложу)
 
Последнее редактирование:
Назад
Сверху