Дикс
11.07.2009, 13:37
Продемонстрирую работу своей небольшой библиотечки. Выкалдываю исключительно для критики, код сыроват, но использование в любых целях возможно и допустимо.
На самом деле библиотечка значительно больше, уже почти доросла до фреймворка, на котором я строил ботов для контакта и одноклассников, но другие классы ещё не готовы для опубликования - слишком многое хочется изменить и улучшить.
Вот урезанная библиотека:
<?php
/**
* aquascript - helpers for webscripts
* v 2.0 @ 18.06.2009-11.07.2009
* by deex icq 86776690 Freedomscripts.org
*/
class aquaCurl
{
private $ptr = 0;
private $lastResponse = '';
// все ключи описаны в конце этого скрипта
private $options = array(
CURLOPT_URL => '',
CURLOPT_POST => 0, // method POST
CURLOPT_HEADER => 1, // show headers
CURLOPT_NOBODY => 0, // disable body
CURLOPT_FAILONERROR => 0,
CURLOPT_TIMEOUT => 3600,
CURLOPT_VERBOSE => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_POSTFIELDS => '', // post data. Content-Type: ARRAY - multipart/form-data, STRING - application/x-www-form-urlencoded
CURLOPT_RETURNTRANSFER => 1, // return response
CURLOPT_SSL_VERIFYPEER => 0, // verify ssl sertificat
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
CURLOPT_TIMEOUT => 30,
// CURLOPT_HTTPHEADER => array("Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7;","Keep-Alive: 300","Connection: keep-alive","Accept: */*")
);
private $settingsRestore = array();
public $login = '';
public $pass = '';
// reset options
public function rst()
{
$this->options = $this->settingsRestore;
}
function __construct()
{
if (!extension_loaded('curl'))
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
dl('curl.dll');
else
dl('curl.so');
if (!extension_loaded('curl'))
die("<b>Unable to load extension Curl! Application Exit</b><br/>");
$this->settingsRestore = $this->options;
}
public function setAuth($login, $pass)
{
$this->login = $login;
$this->pass = $pass;
}
public function set($key, $val)
{
$this->options[$key] = $val;
}
public function exec($return = 1)
{
$this->ptr = curl_init();
if(!$this->ptr)
die('curl not initialized');
if($this->options[CURLOPT_POSTFIELDS] != '' || sizeof($this->options[CURLOPT_POSTFIELDS]) > 1)
$this->options[CURLOPT_POST] = 1;
curl_setopt($this->ptr, CURLOPT_RETURNTRANSFER, $this->options[CURLOPT_RETURNTRANSFER]);
curl_setopt_array($this->ptr, $this->options);
$this->lastResponse = curl_exec($this->ptr);
if($return)
return $this->lastResponse;
else
return $this;
}
public function debug()
{
$response = '<strong>Info</strong><br /><br />';
$info = curl_getinfo($this->ptr);
foreach($info as $k => $v)
{
if(strstr($k, 'size'))
$v = ($v / 1024) . ' kb';
$response .= '<span style="color: #777">'.$k.':</span> '.$v.'<br />';
}
$response .= '<br />';
if($errNo = curl_errno($this->ptr))
$response .= '<strong>Error #'.$errNo.':</strong> '.curl_error($this->ptr).'<br />';
return $response;
}
public function getResponseCode()
{
return curl_getinfo($this->ptr, CURLINFO_HTTP_CODE);
}
public function getCookie()
{
$parse = array();
preg_match_all("/Set-Cookie: ([0-9a-zA-Z\_\-=]*); /i", $this->lastResponse, $parse);
return (isset($parse[1]) && sizeof($parse[1]))? implode('; ', $parse[1]) : '';
}
public function setCookie($cookie)
{
$this->options[CURLOPT_COOKIE] = trim($cookie);
return $this;
}
public function clearCookie()
{
$this->options[CURLOPT_COOKIE] = '';
return $this;
}
function __destruct()
{
if($this->ptr)
curl_close($this->ptr);
if(isset($_SESSION['curl_cookies']))
unset($_SESSION['curl_cookies']);
}
}
//================================================== ============================
class antiCaptcha
{
private $timeOut = 5; // timeout before read result
private $acKey = ''; // ac-service.info key
private $captchaID = 0; // when service get captcha - its return captcha id
private $imageType = 'jpg';
private $url = array(
'sendcaptcha' => 'http://ac-service.info/in.php',
'getinfo' => 'http://ac-service.info/res.php');
private $codes = array(
'in' => array(
'ERROR_KEY_DOES_NOT_EXIST' => 'incorrect anti-captcha key',
'ERROR_NO_SLOT_AVAILABLE' => 'service busy, please try later',
'ERROR_ZERO_CAPTCHA_FILESIZE' => 'captcha is empty file',
'ERROR_TOO_BIG_CAPTCHA_FILESIZE' => 'captcha size bigger than 30 kb',
'ERROR_WRONG_FILE_EXTENSION' => 'incorrect file extension (gif,jpg,png)'
),
'res' => array(
'ERROR_KEY_DOES_NOT_EXIST' => 'incorrect anti-captcha key',
'ERROR_WRONG_ID_FORMAT' => 'uploaded captcha ID is not a number',
'ERROR_NO_SUCH_CAPCHA_ID' => 'uploaded captcha ID is incorrect',
'ERROR_URL_METHOD_FORBIDDEN' => 'method disabled',
'CAPCHA_NOT_READY' => 'please wait..',
'OK_REPORT_RECORDED' => 'complaint writed (only for reportbad function)',
)
);
private $captchaBody = '';
private $curl = '';
public $error = '';
public function __construct($acKey, $timeOut = 5, $imageType = 'jpg', $curl)
{
$this->timeOut = $timeOut;
$this->acKey = $acKey;
$this->imageType = $imageType;
$this->curl = &$curl;
}
public function get($url, $cookie = '')
{
$this->curl->rst();
$this->curl->set(CURLOPT_URL, $url);
$this->curl->set(CURLOPT_BINARYTRANSFER, 1);
$this->curl->set(CURLOPT_HEADER, 0);
if($cookie)
$this->curl->setCookie($cookie);
else
$this->curl->clearCookie();
$this->captchaBody = $this->curl->exec();
return ($this->captchaBody)? 1 : 0;
}
// get captcha body
public function send()
{
$postData = array(
'method' => 'base64',
'key' => $this->acKey,
'body' => base64_encode($this->captchaBody),
'ext' => $this->imageType
);
$this->curl->rst();
$this->curl->set(CURLOPT_URL, $this->url['sendcaptcha']);
$this->curl->set(CURLOPT_POSTFIELDS, $postData);
$this->curl->set(CURLOPT_HEADER, 1);
$this->curl->set(CURLOPT_NOBODY, 0);
$this->curl->set(CURLOPT_RETURNTRANSFER, 1);
$return = $this->curl->clearCookie()->exec();
if(strstr($return, 'OK|'))
{
preg_match('/OK\|(.*)/', $return, $resp);
$this->captchaID = $resp[1];
return 1;
}else{
$this->error = (isset($this->codes['in'][$return]))? $this->codes['in'][$return] : 'cant send';
return 0;
}
}
public function save($name)
{
if($this->captchaBody)
{
file_put_contents($name, $this->captchaBody);
return 1;
}else
return 0;
}
public function load($captcha)
{
$this->captchaBody = file_get_contents($captcha);
return !!$this->captchaBody;
}
public function recognize()
{
$tries = 5;
while($tries--)
{
$postData = array(
'key' => $this->acKey,
'action' => 'get',
'id' => $this->captchaID
);
$this->curl->rst();
$this->curl->set(CURLOPT_URL, $this->url['getinfo']);
$this->curl->set(CURLOPT_POSTFIELDS, $postData);
$this->curl->set(CURLOPT_HEADER, 1);
$this->curl->set(CURLOPT_RETURNTRANSFER, 1);
$this->curl->set(CURLOPT_NOBODY, 0);
$this->curl->set(CURLOPT_FOLLOWLOCATION, 1);
$return = $this->curl->clearCookie()->exec();
if(strstr($return, 'OK|'))
{
preg_match('/OK\|(.*)/', $return, $resp);
return $resp[1];
}else{
sleep($this->timeOut);
}
}
}
public function simple($first, $second = '')
{
$res = (stristr($first, 'http://'))? $this->get($first, $second) : $this->load($first);
if($res && $this->send())
return $this->recognize();
}
}
В данном случае работу с aquacurl я описывать не буду, там всё интуитивно понятно :cool:
Приведу примеры распознавания капчи с помощью ac-service.info (AntiCaptcha)
//убираем лимит, включаем ошибки, инклудим библиотеку
set_time_limit(0);
error_reporting(7);
include('ascript.php');
// url до капчи, куки (опционально), ключ антикапчи (брать на сайте сервиса)
$url = 'http://vkontakte.ru/captcha.php?s=1&sid=248439795815';
$cookie = 'куки';
$acKey = 'abd6*******426';
// инициализируем класс работы с курл
$curl = new aquacurl;
// инициализируем класс работы с антикапчей
// передаём ей ключ, задержку в секундах при проверке результата распознания
// капчи на сервисе, формат капчи, ссылку на созданный класс работы с curl
$ac = new anticaptcha($acKey, 5, 'jpg', &$curl);
// ================ МЕТОД 1 ПРОСТОЙ
// передали урл и куки (опционально) - получили код капчи
$key = $ac->simple($url, $cookie);
// либо передали имя файла (ну и путь если надо)
$key = $ac->simple('captcha.jpg');
// ================ МЕТОД 2 РАСШИРЕННЫЙ
// грузим капчу с урла (+ куки)
$ac->get($url, $cookie);
// если удалось отправить
if($ac->send())
{
// распознаем
$key = $ac->recognize();
// заодно смотрим ошибки
$error = $ac->error;
}
// если капча уже есть в файле, то грузим из файла
$ac->load('captcha.jpg'); // а потом отправляем и распознаем
// если надо сохрнить капчу - указываем имя файла
$ac->save('captcha.jpg');
Вот и всё :)
Надеюсь код окажется кому-либо полезным, в любом случае я жду конструктивной критики и замечаний.
На самом деле библиотечка значительно больше, уже почти доросла до фреймворка, на котором я строил ботов для контакта и одноклассников, но другие классы ещё не готовы для опубликования - слишком многое хочется изменить и улучшить.
Вот урезанная библиотека:
<?php
/**
* aquascript - helpers for webscripts
* v 2.0 @ 18.06.2009-11.07.2009
* by deex icq 86776690 Freedomscripts.org
*/
class aquaCurl
{
private $ptr = 0;
private $lastResponse = '';
// все ключи описаны в конце этого скрипта
private $options = array(
CURLOPT_URL => '',
CURLOPT_POST => 0, // method POST
CURLOPT_HEADER => 1, // show headers
CURLOPT_NOBODY => 0, // disable body
CURLOPT_FAILONERROR => 0,
CURLOPT_TIMEOUT => 3600,
CURLOPT_VERBOSE => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_POSTFIELDS => '', // post data. Content-Type: ARRAY - multipart/form-data, STRING - application/x-www-form-urlencoded
CURLOPT_RETURNTRANSFER => 1, // return response
CURLOPT_SSL_VERIFYPEER => 0, // verify ssl sertificat
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
CURLOPT_TIMEOUT => 30,
// CURLOPT_HTTPHEADER => array("Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7;","Keep-Alive: 300","Connection: keep-alive","Accept: */*")
);
private $settingsRestore = array();
public $login = '';
public $pass = '';
// reset options
public function rst()
{
$this->options = $this->settingsRestore;
}
function __construct()
{
if (!extension_loaded('curl'))
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
dl('curl.dll');
else
dl('curl.so');
if (!extension_loaded('curl'))
die("<b>Unable to load extension Curl! Application Exit</b><br/>");
$this->settingsRestore = $this->options;
}
public function setAuth($login, $pass)
{
$this->login = $login;
$this->pass = $pass;
}
public function set($key, $val)
{
$this->options[$key] = $val;
}
public function exec($return = 1)
{
$this->ptr = curl_init();
if(!$this->ptr)
die('curl not initialized');
if($this->options[CURLOPT_POSTFIELDS] != '' || sizeof($this->options[CURLOPT_POSTFIELDS]) > 1)
$this->options[CURLOPT_POST] = 1;
curl_setopt($this->ptr, CURLOPT_RETURNTRANSFER, $this->options[CURLOPT_RETURNTRANSFER]);
curl_setopt_array($this->ptr, $this->options);
$this->lastResponse = curl_exec($this->ptr);
if($return)
return $this->lastResponse;
else
return $this;
}
public function debug()
{
$response = '<strong>Info</strong><br /><br />';
$info = curl_getinfo($this->ptr);
foreach($info as $k => $v)
{
if(strstr($k, 'size'))
$v = ($v / 1024) . ' kb';
$response .= '<span style="color: #777">'.$k.':</span> '.$v.'<br />';
}
$response .= '<br />';
if($errNo = curl_errno($this->ptr))
$response .= '<strong>Error #'.$errNo.':</strong> '.curl_error($this->ptr).'<br />';
return $response;
}
public function getResponseCode()
{
return curl_getinfo($this->ptr, CURLINFO_HTTP_CODE);
}
public function getCookie()
{
$parse = array();
preg_match_all("/Set-Cookie: ([0-9a-zA-Z\_\-=]*); /i", $this->lastResponse, $parse);
return (isset($parse[1]) && sizeof($parse[1]))? implode('; ', $parse[1]) : '';
}
public function setCookie($cookie)
{
$this->options[CURLOPT_COOKIE] = trim($cookie);
return $this;
}
public function clearCookie()
{
$this->options[CURLOPT_COOKIE] = '';
return $this;
}
function __destruct()
{
if($this->ptr)
curl_close($this->ptr);
if(isset($_SESSION['curl_cookies']))
unset($_SESSION['curl_cookies']);
}
}
//================================================== ============================
class antiCaptcha
{
private $timeOut = 5; // timeout before read result
private $acKey = ''; // ac-service.info key
private $captchaID = 0; // when service get captcha - its return captcha id
private $imageType = 'jpg';
private $url = array(
'sendcaptcha' => 'http://ac-service.info/in.php',
'getinfo' => 'http://ac-service.info/res.php');
private $codes = array(
'in' => array(
'ERROR_KEY_DOES_NOT_EXIST' => 'incorrect anti-captcha key',
'ERROR_NO_SLOT_AVAILABLE' => 'service busy, please try later',
'ERROR_ZERO_CAPTCHA_FILESIZE' => 'captcha is empty file',
'ERROR_TOO_BIG_CAPTCHA_FILESIZE' => 'captcha size bigger than 30 kb',
'ERROR_WRONG_FILE_EXTENSION' => 'incorrect file extension (gif,jpg,png)'
),
'res' => array(
'ERROR_KEY_DOES_NOT_EXIST' => 'incorrect anti-captcha key',
'ERROR_WRONG_ID_FORMAT' => 'uploaded captcha ID is not a number',
'ERROR_NO_SUCH_CAPCHA_ID' => 'uploaded captcha ID is incorrect',
'ERROR_URL_METHOD_FORBIDDEN' => 'method disabled',
'CAPCHA_NOT_READY' => 'please wait..',
'OK_REPORT_RECORDED' => 'complaint writed (only for reportbad function)',
)
);
private $captchaBody = '';
private $curl = '';
public $error = '';
public function __construct($acKey, $timeOut = 5, $imageType = 'jpg', $curl)
{
$this->timeOut = $timeOut;
$this->acKey = $acKey;
$this->imageType = $imageType;
$this->curl = &$curl;
}
public function get($url, $cookie = '')
{
$this->curl->rst();
$this->curl->set(CURLOPT_URL, $url);
$this->curl->set(CURLOPT_BINARYTRANSFER, 1);
$this->curl->set(CURLOPT_HEADER, 0);
if($cookie)
$this->curl->setCookie($cookie);
else
$this->curl->clearCookie();
$this->captchaBody = $this->curl->exec();
return ($this->captchaBody)? 1 : 0;
}
// get captcha body
public function send()
{
$postData = array(
'method' => 'base64',
'key' => $this->acKey,
'body' => base64_encode($this->captchaBody),
'ext' => $this->imageType
);
$this->curl->rst();
$this->curl->set(CURLOPT_URL, $this->url['sendcaptcha']);
$this->curl->set(CURLOPT_POSTFIELDS, $postData);
$this->curl->set(CURLOPT_HEADER, 1);
$this->curl->set(CURLOPT_NOBODY, 0);
$this->curl->set(CURLOPT_RETURNTRANSFER, 1);
$return = $this->curl->clearCookie()->exec();
if(strstr($return, 'OK|'))
{
preg_match('/OK\|(.*)/', $return, $resp);
$this->captchaID = $resp[1];
return 1;
}else{
$this->error = (isset($this->codes['in'][$return]))? $this->codes['in'][$return] : 'cant send';
return 0;
}
}
public function save($name)
{
if($this->captchaBody)
{
file_put_contents($name, $this->captchaBody);
return 1;
}else
return 0;
}
public function load($captcha)
{
$this->captchaBody = file_get_contents($captcha);
return !!$this->captchaBody;
}
public function recognize()
{
$tries = 5;
while($tries--)
{
$postData = array(
'key' => $this->acKey,
'action' => 'get',
'id' => $this->captchaID
);
$this->curl->rst();
$this->curl->set(CURLOPT_URL, $this->url['getinfo']);
$this->curl->set(CURLOPT_POSTFIELDS, $postData);
$this->curl->set(CURLOPT_HEADER, 1);
$this->curl->set(CURLOPT_RETURNTRANSFER, 1);
$this->curl->set(CURLOPT_NOBODY, 0);
$this->curl->set(CURLOPT_FOLLOWLOCATION, 1);
$return = $this->curl->clearCookie()->exec();
if(strstr($return, 'OK|'))
{
preg_match('/OK\|(.*)/', $return, $resp);
return $resp[1];
}else{
sleep($this->timeOut);
}
}
}
public function simple($first, $second = '')
{
$res = (stristr($first, 'http://'))? $this->get($first, $second) : $this->load($first);
if($res && $this->send())
return $this->recognize();
}
}
В данном случае работу с aquacurl я описывать не буду, там всё интуитивно понятно :cool:
Приведу примеры распознавания капчи с помощью ac-service.info (AntiCaptcha)
//убираем лимит, включаем ошибки, инклудим библиотеку
set_time_limit(0);
error_reporting(7);
include('ascript.php');
// url до капчи, куки (опционально), ключ антикапчи (брать на сайте сервиса)
$url = 'http://vkontakte.ru/captcha.php?s=1&sid=248439795815';
$cookie = 'куки';
$acKey = 'abd6*******426';
// инициализируем класс работы с курл
$curl = new aquacurl;
// инициализируем класс работы с антикапчей
// передаём ей ключ, задержку в секундах при проверке результата распознания
// капчи на сервисе, формат капчи, ссылку на созданный класс работы с curl
$ac = new anticaptcha($acKey, 5, 'jpg', &$curl);
// ================ МЕТОД 1 ПРОСТОЙ
// передали урл и куки (опционально) - получили код капчи
$key = $ac->simple($url, $cookie);
// либо передали имя файла (ну и путь если надо)
$key = $ac->simple('captcha.jpg');
// ================ МЕТОД 2 РАСШИРЕННЫЙ
// грузим капчу с урла (+ куки)
$ac->get($url, $cookie);
// если удалось отправить
if($ac->send())
{
// распознаем
$key = $ac->recognize();
// заодно смотрим ошибки
$error = $ac->error;
}
// если капча уже есть в файле, то грузим из файла
$ac->load('captcha.jpg'); // а потом отправляем и распознаем
// если надо сохрнить капчу - указываем имя файла
$ac->save('captcha.jpg');
Вот и всё :)
Надеюсь код окажется кому-либо полезным, в любом случае я жду конструктивной критики и замечаний.