Publicado por Lino Uruñuela el 1 de febrero del 2021
Ya hemos visto cómo podemos comprobar y monitorizar qué URLs renderiza Google, pero si queremos ir un poco más allá también podemos capturar y guardar en Google Analytics qué errores JavaScript se producen cuándo Google ejecuta el código JavaScript para renderizar el contenido.
Cuándo los usuarios interaccionan con los elementos del HTML de una página, ya sea haciendo click en alguna parte de la pantalla o rellenando un formulario, o cargando imágenes mediante Lazy Load se usa JavaScript para ello, y este JavaScript se ejecuta en el navegador del usuario.
Eso quiere decir, que si se produce un error en ese código no podremos verlo ya que no queda registro en el servidor sino en el navegador del usuario. A veces los errores en JavaScript bloquean otras acciones que se deberían realizar pero que debido a algún fallo en el código no se hace y esto puede ser crítico ya que Google no vería ese contenido o elementos que deberían obtenerse mediante la ejecución JavaScript.
Ejemplo de error generado adrede para comprobar el código
Para poder saber si existen errores críticos cuando Google ejecuta código JavaScript podemos aprovechar la misma solución que en el artículo de cómo monitorizar la ejecución de código JavaScript por parte de Google (para renderizar el contenido) aplicando unos ligeros cambios a nuestro código anterior
Para ello, al igual que la vez anterior capturaremos un evento JavaScript, concretamente con esta línea "window.addEventListener('error', function(e)" , para que cuando se produzca se ejecute una función que nos permite trackear estos errores y anotarlos en Google Analytics de la misma manera que hicimos en el post anterior, con la diferencia de que esta función se ejecutará únicamente cuándo se genere un error JavaScript.
window.addEventListener('error', function(e) { var botPattern = "googlebot|Googlebot-Mobile|Googlebot-Image|Google favicon|Mediapartners-Google"; var re = new RegExp(botPattern, 'i'); var userAgent = navigator.userAgent; if (re.test(userAgent)) { var client = new XMLHttpRequest(); var ErroresURL='https://www.mecagoenlos.com/ErrorRenderizadaGoogle.gif?UrlOrigen='+window.location.href+'&mensajeError='+e.message+'&UA='+unescape(encodeURIComponent(userAgent))+'&LineaError='+e.lineno.toString(); client.open('GET',ErroresURL); client.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8'); client.send(e); });
Con este código, cuando se genere un error JavaScript, se ejecutará la función, desde la cual llamaremos a otro pixel transparente "ErrorRenderizadaGoogle.gif" añadiendo como parámetros la URL actual en la que está el usuario, el mensaje de error que devuelve el error y el User Agent, es decir hacemos una llamada a una URL de este tipo
https://www.mecagoenlos.com/ErrorRenderizadaGoogle.gif?UrlOrigen='+window.location.href+'&mensajeError='+e.message+'&UA='+unescape(encodeURIComponent(userAgent))
Como en el anterior post, en el fichero .htaccess crearemos las reglas para que cuándo se solicite la URL del pixel transparente sea otro fichero PHP el que se ejecute
RewriteCond %{REQUEST_URI} ErrorRenderizadaGoogle.gif RewriteRule ErrorRenderizadaGoogle.gif(.*)$ https://www.mecagoenlos.com/ErrorRenderizadoJS.php$1
De esta forma, cuando se solicite la URL de la imagen "https://www.mecagoenlos.com/ErrorRenderizadaGoogle.gif" realmente se ejecutará nuestro fichero PHP "ErrorRenderizadoJS.php"
Desde este fichero se comprobará si es realmente Google el que está ejecutando ese código y crearemos una llamada a Google Analytics (mediante el protocolo de medición de Google Analytics) para generar un evento que tendrá como categoría "Error-Renderizado-Googlebot", como acción del evento la URL dónde se ha producido y en la etiqueta del evento añadiremos el mensaje de error JavaScript que se generó en el navegador del cliente.
header("Pragma-directive: no-cache"); header("Cache-directive: no-cache"); header("Cache-control: no-cache"); header("Pragma: no-cache"); header("Expires: 0"); $src = $_SERVER['HTTP_REFERER']; $UA=$_GET["UA"]; $mensajeError=$_GET["mensajeError"]; $tipo = getimagesize("ImagenRenderizadaGoogle.gif"); $imagen = "ImagenRenderizadaGoogle.gif"; function comprobarGoogle($Ip){ $hostname=gethostbyaddr($Ip); $ip_by_hostname=gethostbyname($hostname); if(preg_match("/googlebot/i",$hostname)) if ($ip_by_hostname == $Ip) return true; else return false; else return false; } $botname="inicial"; $bots = array('Mediapartners-Google[ /]([0-9.]{1,10})' => 'Google Mediapartners', 'Mediapartners-Google' => 'Google Mediapartners', 'Googl(e|ebot)(-Image)/([0-9.]{1,10})' => 'Google Image', 'Googl(e|ebot)(-Image)/' => 'Google Image', '^gsa-crawler' => 'Google', 'Googl(e|ebot)(-Sitemaps)/([0-9.]{1,10})?' => 'Google-Sitemaps', 'GSiteCrawler[ /v]*([0-9.a-z]{1,10})?' => 'Google-Sitemaps', 'Googl(e|ebot)(-Sitemaps)' => 'Google-Sitemaps', 'Mobile.*Googlebot' => 'Google-Mobile', '^AdsBot-Google' => 'Google-AdsBot', '^Feedfetcher-Google' => 'Google-Feedfetcher', 'compatible; Google Desktop' => 'Google Desktop', 'Googlebot' => 'Googlebot'); foreach( $bots as $pattern => $bot ) { if ( preg_match( '#'.$pattern.'#i' , $UA) == 1 ) { $botname = preg_replace ( "/\\s{1,}/i" , '-' , $bot ); break; } } if(comprobarGoogle($_SERVER['REMOTE_ADDR'])) $esGoogle="Real"; else $esGoogle="Fake"; class BotTracker { static function track($s, $params){ $bot = ""; $data = array( 'v' => 1, 'tid' => 'UA-XXXXXX-1', 'cid' => self::generate_uuid(), 't' => 'event', 'dh' => $s['HTTP_HOST'], 'dl' => $s['REQUEST_URI'], 'dr' => $s['HTTP_REFERER'], 'dp' => $s['REQUEST_URI'], 'dt' => $params['page_title'], 'ck' => $s['HTTP_USER_AGENT'], 'uip' => $s['REMOTE_ADDR'], 'ni' => 1, 'ec' => 'Error-Renderizado-Googlebot', 'el' => $params["mensajeError"]." (".$params['UA']." -" .$params['botname']." - ".$params['esGoogle'].")", 'ea' => $params['URLrenderizada'] ); $url = 'http://www.google-analytics.com/collect'; $content = http_build_query($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_USERAGENT, $s['HTTP_USER_AGENT']); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 0); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_ENCODING , "gzip"); curl_setopt($ch, CURLOPT_POSTFIELDS, $content); $result = curl_exec($ch); $info= curl_getinfo($ch); curl_close($ch); } static private function generate_uuid() { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0x0fff ) | 0x4000, mt_rand( 0, 0x3fff ) | 0x8000, mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) ); } } BotTracker::track($_SERVER, array("page_title"=>"Renderizado JS Google","URLrenderizada"=>$src,"esGoogle"=>$esGoogle,"mensajeError"=>$mensajeError,"botname"=>$botname,"UA"=>$UA)); ?>
Ahora ya podemos ver qué errores genera Google cuándo ejecuta JavaScript para renderizar el contenido
Con esta implementación podremos ver los errores concretos que Genera Google cuando ejecuta el código JavaScript, y podemos ver en qué URLs se producen.
Se me ocurren muchas otras cosas a monitorizar en cuanto a la ejecución de JavaScript por parte de Google, como por ejemplo podríamos crear una solución similar para saber si Google realiza determinadas acciones, como hacer scroll, o clicks, o cualquier otro evento mediante JavaScript, pero con esto finalizamos por hoy las publicaciones, en breve más!