[php] Автоматизация работы с addurl Яндекса

Тема в разделе ".:: Готовые решения", создана пользователем wolgast, 14 фев 2009.

Статус темы:
Закрыта.
  1. wolgast

    wolgast

    Регистр.:
    9 дек 2006
    Сообщения:
    296
    Симпатии:
    32
    Я уже как-то писал о том, как "разгадывать капчи"
    статья а сейчас решил развить этот пример в что-то более практичное.

    Цель: автоматизировать добавление страниц в addurl Яндекса (webmaster.yandex.ru)

    Скрипт конечно же на PHP и для определения значений капчи я все также использую сервис anti-captcha.com.

    Вперед…

    Форма с данными отправляется на http://webmaster.yandex.ru/add.xml

    Принимаемые данные:

    url => добавляемый url
    key => идентификатор операции
    rep => значение капчи​

    Основная задача для нас - получить идентификатор операции. Это своего рода идентификатор сессии, только он не прячется в куках. Можно написать регулярное выражение, но я решил использовать одну известную мне полезную функцию

    PHP:
        //возвращает то, что между $left и $right в $str
        
    function cut_str($str$left$right)
        {
        
    $str substr(stristr($str$left), strlen($left));
        
    $leftLen strlen(stristr($str$right));
        
    $leftLen $leftLen ? -($leftLen) : strlen($str);
        
    $str substr($str0$leftLen);
        return 
    $str;
        }
    К примеру чтобы из вот этого

    Код:
    <input type=“hidden” name=“key” value=“41b8227dcc2c765d90386921797db4ca”>
    вытащить идентификатор, использует функцию следующим образом

    PHP:
    $key cut_str($data‘name=”key” value=”‘,’”‘);
    Дальше идем за качпей. Ее получаем по адресу

    http://captcha.yandex.net/image?key={идентификатор операции}​

    Следующим шагом нужно определить значение этой капчи. Об этом я подробно писал раньше. Если значение капчи нам известно, то остается только отправить форму скрипту яндекса.

    PHP:
    $postdata = array(
        
    ‘url’ => $link,
        
    ‘key’ => $key,
        
    ‘rep’ => $captcha_value
        
    );
    PHP:
    $cap geturl(”http://webmaster.yandex.ru/add.xml”,$postdata);
    Вот и все. Кстате для этого метода нет необходимости использовать прокси т.к. капчи вводятся безошибочно, а значит и банить незачто!

    Полный листинг:
    PHP:
    <?php
    /*
     * Автор: koder
     * 13.02.09
     * 
     * Дополнительная информация
     * http://myseoincome.ru/2009/02/php_yandex_addurl/
     * 
     */
    set_time_limit(0);
    //ключь anti-captcha
    $anti_captcha_key '......';
    //файлик с URLами
    $urls file('url.txt');
    $i=1;
    foreach (
    $urls as $link){ //получили адрес
        
    $data geturl('http://webmaster.yandex.ru/');    
        
    $key cut_str($data'name="key" value="','"'); //получили идентификатор сеанса
        
    $captcha geturl('http://captcha.yandex.net/image?key='.$key); //слили капчу
        
        
    $postdata = array(
            
    'method'    => 'base64'
            
    'key'       => $anti_captcha_key
            
    'body'      => base64_encode($captcha),
            
    'ext'         => 'jpg',
            
    'phrase'    => 0,
            
    'regsense'    => 0,
            
    'numeric'    => 0,
            
    'min_len'    => 0,
            
    'max_len'    => 0
        
    );
        
    $rev geturl("http://anti-captcha.com/in.php",$postdata); //отдали капчу антикапче
        
        
    if (substr($rev,0,2)=='OK'){
            
    $anti_captcha_id substr($rev,3);
        }else{
            echo 
    "Upload ERROR";
            exit;
        }
        
    sleep(20); //подождем 20сек. пока ее разгадают
        
        
    $postdata = array(
            
    'key'       => $anti_captcha_key,
            
    'action'    => 'get',
            
    'id'     => $anti_captcha_id
        
    );
            
        
    $cap geturl("http://anti-captcha.com/res.php",$postdata); //ответ от антикапчи    
        
    if (substr($cap,0,2)=='OK'){
            
    $captcha_value substr($cap,3);
        }else{
            echo 
    $cap;
            exit;
        }    

        
    $postdata = array(
            
    'url' => $link,
            
    'key' => $key,
            
    'rep' => $captcha_value
        
    );
        
        
    $cap geturl("http://webmaster.yandex.ru/add.xml",$postdata); //спамим в яндекс
        
        
    echo $i.": ".$link.' - ';
        if (
    strpos($cap'успешно добавлен')){
            echo 
    'ok<br>';
        }elseif (
    strpos($cap'уже проиндексирован')){
            echo 
    'в индексе<br>';
        }elseif (
    strpos($cap'является зеркалом')){
            echo 
    'зеркало<br>';
        }elseif (
    strpos($cap'неверно указали цифровой код')){
            echo 
    'Captcha error<br>';
            
    $postdata = array(
                    
    'key'       => $anti_captcha_key
                    
    'action'    => 'reportbad',
                    
    'id'         => $anti_captcha_id                
                
    );                            
            
    $cap geturl("http://anti-captcha.com/res.php",$postdata);        
        }elseif (
    strpos($cap'robots.txt')){
            echo 
    'запрещен в файле robots.txt<br>';
        }elseif (
    strpos($cap'отличный от 200')){
            echo 
    '404<br>';
        }elseif (
    strpos($cap'запрещен к индексированию')){
            echo 
    'ban<br>';        
        }else{        
            echo 
    'error<br>';
            
    //echo $cap;
            //exit;
        
    }
    $i++;    
    }

        
    //возвращает то, что между $left и $right в $str
        
    function cut_str($str$left$right)
        {
            
    $str substr(stristr($str$left), strlen($left));
            
    $leftLen strlen(stristr($str$right));
            
    $leftLen $leftLen ? -($leftLen) : strlen($str);
            
    $str substr($str0$leftLen);
            return 
    $str;
        }
        
        
        function 
    geturl($url,$postdata=0)
        {
            
    $poststr="";    
            if (
    $postdata)    
            while (list(
    $name,$value)=each($postdata)){
                if (
    strlen($poststr)>0
                    
    $poststr.="&";
                
    $poststr.=$name."=".urlencode($value);
            }
            
    // инициализация сеанса
            
    $ch curl_init();        
            
    curl_setopt($chCURLOPT_URL$url);        
            
            if (
    $postdata){
                
    curl_setopt($chCURLOPT_POST1);
                
    curl_setopt($chCURLOPT_POSTFIELDS$poststr);            
            }        
            
    curl_setopt($chCURLOPT_USERAGENT'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3');
            
    curl_setopt($chCURLOPT_RETURNTRANSFER1);
            
    $res curl_exec($ch);
            
    curl_close($ch);        
            return 
    $res;
        }
            
    ?>

    Архив со скриптом
    http://myseoincome.ru/2009/02/php_yandex_addurl/yandex/

    Источник статьи http://myseoincome.ru/
     
  2. fuck0ff

    fuck0ff Постоялец

    Регистр.:
    2 сен 2007
    Сообщения:
    92
    Симпатии:
    50
    полезная функция при парсинге всяком =)

    я тоже юзаю ее в таком примерно виде:

    PHP:
    return (string)reset(explode($rightend(explode($left$data))));
    если ожидаешь число можно так:

    PHP:
    return (int)end(explode("ИЦ - "$urls['Yandex CY']['Rank']));
    обрежет все справа, кроме циферок, если не нашлось - вернет 0 :)
     
  3. HalliK

    HalliK Постоялец

    Регистр.:
    4 фев 2007
    Сообщения:
    117
    Симпатии:
    166
    Эти все телодвижения лишние! :) Есть у антикапчи своя функция, она сама все сделает, нужно только с нужными параметрами её вызвать. Собственно вот она (вариант через сокеты:(
    PHP:
    function recognize($filename$apikey$is_verbose true$rtimeout 5$mtimeout 120$is_phrase 0$is_regsense 0$is_numeric 0$min_len 0$max_len 0){
        if (!
    file_exists($filename)) {
            if (
    $is_verbose) echo "file $filename not found\n";
            return 
    false;
        }
        
    $fp=fopen($filename,"r");
        if (
    $fp!=false) {
            
    $body="";
            while (!
    feof($fp)) $body.=fgets($fp,1024);
            
    fclose($fp);
            
    $ext=strtolower(substr($filename,strpos($filename,".")+1));
        }
        else {
            if (
    $is_verbose) echo "could not read file $filename\n";
            return 
    false;
        }
        if (
    $ext=="jpg"$conttype="image/pjpeg";
        if (
    $ext=="gif"$conttype="image/gif";
        if (
    $ext=="png"$conttype="image/png";
        
        
        
    $sendhost="anti-captcha.com";
        
    $boundary="---------FGf4Fh3fdjGQ148fdh";
        
    $content="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"method\"\r\n";
        
    $content.="\r\n";
        
    $content.="post\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"key\"\r\n";
        
    $content.="\r\n";
        
    $content.="$apikey\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"phrase\"\r\n";
        
    $content.="\r\n";
        
    $content.="$is_phrase\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"regsense\"\r\n";
        
    $content.="\r\n";
        
    $content.="$is_regsense\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"numeric\"\r\n";
        
    $content.="\r\n";
        
    $content.="$is_numeric\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"min_len\"\r\n";
        
    $content.="\r\n";
        
    $content.="$min_len\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"max_len\"\r\n";
        
    $content.="\r\n";
        
    $content.="$max_len\r\n";
        
    $content.="--$boundary\r\n";
        
    $content.="Content-Disposition: form-data; name=\"file\"; filename=\"capcha.$ext\"\r\n";
        
    $content.="Content-Type: $conttype\r\n";
        
    $content.="\r\n";
        
    $content.=$body."\r\n"//тело файла
        
    $content.="--$boundary--";
        
        
    $poststr="POST http://$sendhost/in.php HTTP/1.0\r\n";
        
    $poststr.="Content-Type: multipart/form-data; boundary=$boundary\r\n";
        
    $poststr.="Host: $sendhost\r\n";
        
    $poststr.="Content-Length: ".strlen($content)."\r\n\r\n";
        
    $poststr.=$content;
        
    // echo $poststr;
        
        
    if ($is_verbose) echo "connecting $sendhost...";
        
    $fp=fsockopen($sendhost,80,$errno,$errstr,30);
        if (
    $fp!=false) {
            if (
    $is_verbose) echo "OK\n";
            if (
    $is_verbose) echo "sending request ".strlen($poststr)." bytes...";
            
    fputs($fp,$poststr);
            if (
    $is_verbose) echo "OK\n";
            if (
    $is_verbose) echo "getting response...";
            
    $resp="";
            while (!
    feof($fp)) $resp.=fgets($fp,1024);
            
    fclose($fp);
            
    $result=substr($resp,strpos($resp,"\r\n\r\n")+4);
            if (
    $is_verbose) echo "OK\n";
        }
        else {
            if (
    $is_verbose) echo "could not connect to anti-captcha\n";
            if (
    $is_verbose) echo "socket error: $errno ( $errstr )\n";
            return 
    false;
        }
        if (
    strpos($result"ERROR")!==false or strpos($result"<HTML>")!==false) {
            if (
    $is_verbose) echo "server returned error: $result\n";
            return 
    false;
        }
        else {
            
    $ex explode("|"$result);
            global 
    $captcha_id;
            
    $captcha_id $ex[1];
            if (
    $is_verbose) echo "captcha sent, got captcha ID $captcha_id\n";
            
    $waittime 0;
            if (
    $is_verbose) echo "waiting for $rtimeout seconds\n";
            
    sleep($rtimeout);
            while(
    true) {
                
    $result file_get_contents('http://anti-captcha.com/res.php?key='.$apikey.'&action=get&id='.$captcha_id);
                if (
    strpos($result'ERROR')!==false) {
                    if (
    $is_verbose) echo "server returned error: $result\n";
                    return 
    false;
                }
                if (
    $result=="CAPCHA_NOT_READY") {
                    if (
    $is_verbose) echo "captcha is not ready yet\n";
                    
    $waittime += $rtimeout;
                    if (
    $waittime>$mtimeout) {
                        if (
    $is_verbose) echo "timelimit ($mtimeout) hit\n";
                        break;
                    }
                    if (
    $is_verbose) echo "waiting for $rtimeout seconds\n";
                    
    sleep($rtimeout);
                }
                else {
                    
    $ex explode('|'$result);
                    if (
    trim($ex[0])=='OK') return trim($ex[1]);
                }
            }
            
            return 
    false;
        }
    }
    А вызываем так:
    PHP:
    $captcha recognize($filename$apikeyfalse$rtimeout 5$mtimeout 60);
    можно еще несколько параметров добавить при вызове, их больше, это всего лишь пример, поясню - $filename - url капчи на локале, $apikey - ваш идентификатор на антикапче, true/false - показывать/не показывать сообщения о прцессе, $rtimeout - через каждые N сек получать ответ, и последний параметр в моем примере - таймаут для этой капчи.
    Не стоит ждать, надо запрашивать ответ постоянно, потому что у меня бывает за 5 секунд разгадывают, бывает дольше 20, время лучше не терять, это же автомат;)

    Чуть не забыл (парсинг $key:(
    PHP:
    preg_match('|<input type=“hidden” name=“key” value=“(.*?)”>|is'$cap$result);
    $key $result[1];
     
  4. wolgast

    wolgast

    Регистр.:
    9 дек 2006
    Сообщения:
    296
    Симпатии:
    32
    Скрипт можно совершенствовать до бесконечности. Я показал максимально облегченный вариант
     
  5. sergeysnl

    sergeysnl Читатель

    Заблокирован
    Регистр.:
    10 фев 2008
    Сообщения:
    331
    Симпатии:
    100
    я в php только новичок, при попытке запустить скрипт пишет
    На 114 строчке
    PHP:
            $ch curl_init();
    Не знаю что делать, подскажите пожалуйста.
     
  6. wolgast

    wolgast

    Регистр.:
    9 дек 2006
    Сообщения:
    296
    Симпатии:
    32
    У тебя не установлен модуль php_curl
     
  7. voooz

    voooz

    Регистр.:
    8 дек 2006
    Сообщения:
    360
    Симпатии:
    41
    Вот здесь подобный сервис уже продают
    http://forum.searchengines.ru/showthread.php?t=325134
     
Статус темы:
Закрыта.