dig555
Постоялец
- Регистрация
- 22 Июн 2007
- Сообщения
- 365
- Реакции
- 160
- Автор темы
- #1
Есть парсер. Неважно чего. Работать должен длительное время. Нужно после того как я его закинул на сервак и запустил, иметь возможность, выключить свой комп и идти спать. А скрипт пусть работает на сервере до победного конца. Я знаю точно, что возможно. Но не знаю как
Буду благодарен любым ссылкам на примеры/мануалы/вашим советам. Ниже пример парсера вордстата, который был написан для меня года полтора назад. В нём эта фишка реализована. Похоже без AJAX тут не обойтись?
Полностью:
Буду благодарен любым ссылкам на примеры/мануалы/вашим советам. Ниже пример парсера вордстата, который был написан для меня года полтора назад. В нём эта фишка реализована. Похоже без AJAX тут не обойтись?
PHP:
if ((STATUS=='BUSY')||(STATUS=='DONE')) {
tpl_exe(TPL_HEAD);
tpl_exe(TPL_AJAX,array('action'=>$_SERVER['PHP_SELF']));
tpl_exe(TPL_TAIL);
return;
}
PHP:
<?php
header('Connection: Close');
header('Cache-Control: no-cache');
header('Pragma: nocache');
header('Content-Type: text/html;charset=windows-1251');
#### conf
set_time_limit(0);
ignore_user_abort(true);
setlocale(LC_ALL,'ru_RU.CP1251');
define('STATUS_FILE','./xparser.st');
define('PROXYLIST','./proxylist.txt');
define('BADWORDS','./badwords.txt');
define('LETTERS','0-9a-zA-ZабвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ');
define('URL','http://wordstat.yandex.ru/advq?rpt=ppc&key=&shw=1&tm=&checkboxes=&text={$WORD}®ions_text=%C2%F1%E5®ions=');
define('NEWDIRPERMS',0744);
define('STATUSUPDATERATE',10000); # частота обновления статуса в мс. для ie ставить не меньше 10000. опера и фокс нормально работают при меньших значениях
#### conf
function get_status() {
return file_get_contents(STATUS_FILE);
}
function set_status( $s) { # (IDLE|BUSY|DONE)|*EXTRA*
$f = fopen(STATUS_FILE,'w');
fputs($f,$s);
fflush($f);
fclose($f);
}
function set_status_busy( $i, $total) {
set_status('BUSY|'.$i.'~'.$total);
}
function x_headers( $s) {
header('Content-Length: '.strlen($s));
echo $s;
}
###### tpl
define('TPL_HEAD','<html>
<head>
<style>
* {
font-family: Tahoma;
font-size: 10pt;
color: black;
}
input, textarea {
background:color: white;
}
input.b, textarea {
border: 1px solid #906090;
}
div.e {
color: yellow;
background-color: red;
margin: -20px -20px 0 -20px;
padding: 10px;
}
</style>
</head>
<body marginheight=0 marginwidth=0 leftmargin=0 topmargin=0>
<table border=0 width=100% height=100% cellpadding=0 cellspacing=0><tr><td align=center>
<table border=1 cellpadding=20 cellspacing=0><tr><td>
');
define('TPL_TAIL','</td></tr></table>
</td></tr></table>
</body>
</html>');
define('TPL_FORM','
<script language=javascript>
function redir() {
setTimeout("document.location=\'${action}\'",1000);
return true;
}
</script>
<form action="{$action}" method=post onsubmit="return redir()">
<input type=hidden name=action value=start />
<table border=0 cellpadding=2 cellspacing=0>
<tr><td colspan=2><b>Параметры парсера</b></td></tr>
<tr><td valign=top>Слова для парсинга</td><td><textarea style="width:300px;height:100px;" name=words>{$words}</textarea></td></tr>
<tr><td>Глубина парсинга</td><td><input type=text style="width:30px;" class=b name=limit value="{$limit}" /> страниц</td></tr>
<tr><td>Метод обхода капчи</td><td><input type=radio name=acaptcha id=asleep value=sleep {$acaptcha_sleep} /> <label for=asleep>sleep( )</label><br /><input type=radio name=acaptcha id=aproxy value=proxy {$acaptcha_proxy} /> <label for=aproxy>прокси</label></td></tr>
<tr><td><label for=afilter>Чистить плохие слова?</label></td><td><input type=checkbox name=filter id=afilter {$filter} /></td></tr>
<tr><td><label for=ashuffle>Перемешивать кеи?</label></td><td><input type=checkbox name=shuffle id=ashuffle {$shuffle} /></td></tr>
<tr><td>Разбить результат по</td><td><input type=text style="width:40px;" class=b name=page value="{$page}" /> кеев</td></tr>
<tr><td>Сохранять в каталог</td><td><input type=text style="width:100px;" class=b name=path value="{$path}" /></td></tr>
<tr><td colspan=2 align=right><input type=submit style="width:40px;" class=b value=Go /></td></tr>
</table>
</form>
');
define('TPL_ERROR','<div class=e>{$msg}</div>');
define('TPL_AJAX','
<script language=javascript src="ajax.js"></script>
<script language=javascript>
var __done;
var __c = 0;
function __parse( s) {
if (s.substr(0,11)=="javascript:") {
eval(s.slice(11));
return false;
}
/* __c++;
document.getElementById("jjj").innerHTML = s.slice(5)+" (a="+__c+")";
return false;*/
return true;
}
var ao;
function refresh() {
ao.sndReq("post","{$action}","action=status");
if (!__done) {
setTimeout("refresh()",'.STATUSUPDATERATE.');
}
}
window.onload = function() {
__done = false;
ao = new AjaxObject101();
ao.funcDone = __parse;
refresh();
}
</script>
<center><b>Процесс пошел</b><br /><br /><div id="jjj">***</div></center>
');
function tpl_exe( $tpl, $args=false) {
if ($args!==false) {
extract($args);
}
echo eval('return "'.str_replace('"','\"',$tpl).'";');
}
###### tpl
function wrap_msg( $s) {
tpl_exe(TPL_HEAD);
echo $s;
tpl_exe(TPL_TAIL);
return 0;
}
function translit($cyr_str) {
$razd="-";
$cyr_str=strtolower($cyr_str);
$tr = array (
"А"=>"a","Б"=>"b","В"=>"v","Г"=>"g",
"Д"=>"d","Е"=>"e","Ж"=>"zh","З"=>"z","И"=>"i",
"Й"=>"y","К"=>"k","Л"=>"l","М"=>"m","Н"=>"n",
"О"=>"o","П"=>"p","Р"=>"r","С"=>"s","Т"=>"t",
"У"=>"u","Ф"=>"f","Х"=>"h","Ц"=>"c","Ч"=>"ch",
"Ш"=>"sh","Щ"=>"sch","Ъ"=>"","Ы"=>"y","Ь"=>"",
"Э"=>"e","Ю"=>"u","Я"=>"ya","а"=>"a","б"=>"b",
"в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh",
"з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l",
"м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
"с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h",
"ц"=>"c","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"",
"ы"=>"y","ь"=>"","э"=>"e","ю"=>"u","я"=>"ya", " " => $razd
);
$text= strtr($cyr_str, $tr);
$text=preg_replace("/[^a-z0-9_ -]+/", "", $text);
return $text;
}
function rulat($words) {
$rus = "АаВЕеКкМНОоРрСсТХх";
$eng = "AaBEeKkMHOoPpCcTXx";
return strtr($words,$eng,$rus);
}
function array_exclude( &$a, $i, $n) {
for ($j=$i+1; $j<$n; $j++) {
$a[$j-1] = $a[$j];
}
}
$x = explode('|',get_status(),2);
define('STATUS',$x[0]);
define('STATUS_MSG',$x[1]);
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'start':
if (STATUS!=='IDLE') {
header('Location: '.$_SERVER['PHP_SELF']);
return;
}
$words = trim(preg_replace('/[^'.LETTERS.']+/',' ',$_POST['words']));
$words = array_unique(explode(' ',$words));
$words = implode(' ',$words);
$limit = (int)$_POST['limit'];
$acaptcha = $_POST['acaptcha'];
$filter = isset($_POST['filter']);
$shuffle = isset($_POST['shuffle']);
$page = (int)$_POST['page'];
$path = trim($_POST['path']);
$fs = array();
if (!$words) {
$fs[] = 'Укажите слова для парсинга';
}
if ($limit<=0) {
$fs[] = 'Укажите глубину парсинга';
}
if ($filter&&!file_exists(BADWORDS)) {
$fs[] = 'Не найден файл с плохими словами';
}
if (($acaptcha=='proxy')&&!file_exists(PROXYLIST)) {
$fs[] = 'Не найден файл со списком прокси';
}
if ($page<=0) {
$fs[] = 'Укажите размер разбиения результата';
}
$path = str_replace('\\','/',$path);
if (substr($path,-1,1)!=='/') {
$path .= '/';
}
if (file_exists($path)&&(!is_dir($path)||!is_writable($path))) {
$fs[] = 'Нет доступа к каталогу';
}
if (!sizeof($fs)&&!file_exists($path)) {
if (!mkdir($path,NEWDIRPERMS)) {
$fs[] = 'Не могу создать каталог';
}
}
if (sizeof($fs)) {
tpl_exe(TPL_HEAD);
tpl_exe(TPL_ERROR,array('msg'=>implode('<br />',$fs)));
tpl_exe(TPL_FORM,array(
'action' => $_SERVER['PHP_SELF'],
'words' => $words,
'limit' => $limit,
'acaptcha_sleep' => $acaptcha=='sleep'?'checked':'',
'acaptcha_proxy' => $acaptcha=='proxy'?'checked':'',
'filter' => $filter?'checked':'',
'shuffle' => $shuffle?'checked':'',
'page' => $page,
'path' => $path
));
tpl_exe(TPL_TAIL);
return;
}
$words = explode(' ',$words);
$words_total = sizeof($words);
$word_count = 0;
set_status_busy(0,$words_total);
$RZ = array();
if ($filter) {
$badwords = strtolower(preg_replace('/\s+/',' ',trim(file_get_contents(BADWORDS))));
$badwords = explode(' ',$badwords);
$badwords = array_flip($badwords);
}
if ($acaptcha=='proxy') {
$proxylist = preg_replace('/\s+/',' ',trim(file_get_contents(PROXYLIST)));
$proxylist = explode(' ',$proxylist);
$proxies = sizeof($proxylist);
}
foreach ($words as $w) {
set_status_busy($word_count,$words_total);
$word_count++;
$RZ[$w] = array(
'paged' => 0,
'grabbed' => 0,
'accepted' => 0
);
$url = str_replace('{$WORD}',urlencode($w),URL);
$buf = array();
for ( $step=0; $step<$limit; $step++) { # by pages
$RZ[$w]['paged']++;
if ($acaptcha=='sleep') {
sleep(rand(5,15));
}
do {
$httpok = true;
$ch=curl_init($url);
if ($acaptcha=='proxy') {
$proxy = rand(0,$proxies-1);
curl_setopt($ch, CURLOPT_PROXY, $proxylist[$proxy]);
}
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_REFERER, "http://yandex.ru");
$content=curl_exec($ch);
if ($acaptcha=='proxy') {
if (curl_errno($ch)) {
$httpok = false;
array_exclude($proxylist,$proxy,$proxies);
$proxies--;
}
}
curl_close($ch);
} while (!$httpok);
$pos = strpos($content,"Что еще");
if ($pos !== false) {
$content = substr($content,0,$pos);
}
$RZ[$w]['grabbed'] += preg_match_all('/tm=">(['.LETTERS.' ]+)<\/a>/',$content,$matches);
foreach ($matches[1] as $v) {
$is_ok = true;
if ($filter) { # filter bad words
$s = explode(' ',$v);
foreach ($s as $t) {
$tl = strtolower($t);
if (isset($badwords[$tl])||isset($badwords[rulat($tl)])) {
$is_ok = false;
break;
}
}
}
if ($is_ok) {
$buf[] = $v;
}
}
if (preg_match('/<a href="(\/advq\?[^"]+)">следующая/',$content,$match)) {
$url = 'http://wordstat.yandex.ru'.str_replace('&','&',$match[1]);
} else {
break; # no more pages
}
}
$RZ[$w]['accepted'] = sizeof($buf);
if ($z=sizeof($buf)) {
if ($shuffle) { # shuffle the keys grabbed
for ($i=1; $i<$z; $i++){
$a = rand(0,$z-1);
$b = rand(0,$z-1);
$ta = $buf[$a];
$tb = $buf[$b];
$buf[$a] = $tb;
$buf[$b] = $ta;
}
}
$buf = array_chunk($buf,$page);
$i = 0;
foreach ($buf as $x) {
$f = fopen($path.translit($w).'-'.(++$i).'.txt','w');
fputs($f,implode("\n",$x));
fclose($f);
}
}
}
$total_grabbed = 0;
$total_accepted = 0;
foreach ($RZ as $x) {
$total_grabbed += $x['grabbed'];
$total_accepted += $x['accepted'];
}
set_status('DONE|Обработано '.$words_total.' слов\nВытянуто '.$total_grabbed.' кеев\nСохранено (в каталог '.$path.') '.$total_accepted.' кеев');
return;
case 'status':
if (STATUS=='BUSY') {
list($a,$b) = explode('~',STATUS_MSG);
x_headers('jjj=>выполнено '.$a.'/'.$b.' ('.(int)(100*$a/$b).'%)');
return;
}
if (STATUS=='DONE') {
set_status('IDLE|');
x_headers('javascript:__done=true;alert("'.STATUS_MSG.'");document.location="'.$_SERVER['PHP_SELF'].'";');
return;
}
return;
case 'stop':
if (STATUS!=='BUSY') {
return;
}
return;
}
}
if ((STATUS=='BUSY')||(STATUS=='DONE')) {
tpl_exe(TPL_HEAD);
tpl_exe(TPL_AJAX,array('action'=>$_SERVER['PHP_SELF']));
tpl_exe(TPL_TAIL);
return;
}
tpl_exe(TPL_HEAD);
tpl_exe(TPL_FORM,array(
'action' => $_SERVER['PHP_SELF'],
'words' => '',
'limit' => '1',
'acaptcha_sleep' => 'checked',
'acaptcha_proxy' => '',
'filter' => '',
'shuffle' => '',
'page' => '1000',
'path' => './'
));
tpl_exe(TPL_TAIL);
?>