Rastreo, indexación y Python: Todo lo que necesitas saber

SEO

Comprender los procesos de rastreo e indexación es fundamental para el éxito de cualquier estrategia SEO. En este artículo, se analizarán en detalle estos conceptos y cómo Python puede ser una herramienta eficaz para optimizarlos.

how Python (using Advertools) can analyze a sitemap. It could show the process of loading a sitemap into a DataFrame and running analyses on it.

La importancia del crawling y la indexación en SEO

Antes de sumergirnos en los aspectos técnicos, es esencial comprender por qué el crawling y la indexación son tan críticos para el SEO:

  1. Si tus páginas no son rastreadas, nunca serán indexadas.
  2. Sin indexación, tus páginas no aparecerán en los resultados de búsqueda.
  3. Un crawling e indexación deficientes pueden afectar negativamente tu rendimiento SEO.

Como SEOs, nuestro objetivo principal es asegurar que nuestros sitios web sean fácilmente rastreables y proporcionar a Google nuestras páginas más importantes para su indexación. Esto nos permitirá comenzar a adquirir tráfico orgánico a través de ellas.

Recordatorio:El crawling y la indexación son procesos diferentes. El crawling es el proceso por el cual los motores de búsqueda descubren tu contenido, mientras que la indexación es el proceso de almacenar y organizar ese contenido para su posterior recuperación. Puedes tener páginas rastreadas pero no indexadas, lo que puede indicar problemas de calidad o relevancia.

crawling

Herramientas para mejorar el crawling y la indexación

Afortunadamente, contamos con diversas herramientas que pueden ayudarnos a mejorar la capacidad de rastreo de nuestros sitios web:

  1. Screaming Frog
  2. Oncrawl
  3. Python

En este artículo, nos centraremos en cómo Python puede ayudarnos a analizar y mejorar nuestro crawling y nuestros indicadores de indexación. Es importante destacar que estas mejoras a menudo conducen a mejores rankings, mayor visibilidad en los SERPs y, en última instancia, más usuarios aterrizando en nuestro sitio web.

Tip experto: No subestimes el poder de las herramientas integradas en los motores de búsqueda. La Google Search Console y Bing Webmaster Tools ofrecen información valiosa sobre el crawling y la indexación de tu sitio.

Solicitar indexación con Python

Para Google

Existen varias formas de solicitar la indexación a Google, aunque ninguna de ellas es perfecta. Analizaremos tres opciones principales:

  1. Selenium y Google Search Console
  2. Hacer ping a un sitemap
  3. API de indexación de Google

1. Selenium y Google Search Console

Esta es, en mi experiencia, la solución más efectiva, aunque tiene sus limitaciones. El proceso implica acceder a Google Search Console desde un navegador utilizando Selenium y replicar el proceso manual de envío de URLs para indexación de forma automatizada.

Es importante señalar que no debemos abusar de este método. Solo debemos usarlo para enviar una página para indexación si su contenido ha sido actualizado o si la página es completamente nueva.

El truco para iniciar sesión en Google Search Console con Selenium es acceder primero al OAUTH Playground. Aquí tienes un ejemplo de código:

import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get('https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=email&access_type=offline&flowName=GeneralOAuthFlow')

time.sleep(10)
form1 = driver.find_element_by_xpath('//*[@id="identifierId"]')
form1.send_keys("<tu dirección de correo electrónico>")
form1.send_keys(Keys.ENTER)

time.sleep(10)
form2 = driver.find_element_by_xpath('//*[@id="password"]/div[1]/div/div[1]/input')
form2.send_keys("<tu contraseña>")
form2.send_keys(Keys.ENTER)

Después de esto, puedes acceder a tu URL de Google Search Console y solicitar la indexación de tus URLs.

Tip: Asegúrate de manejar los casos de error y las excepciones en tu código. La interfaz de Google Search Console puede cambiar, y tu script debe ser lo suficientemente robusto para manejar estos cambios.

2. Hacer ping a un sitemap (método obsoleto)

Es importante destacar que el método de hacer ping a un sitemap ya no es recomendado y pronto quedará obsoleto. Google ha anunciado que dejará de dar soporte a este método en un futuro próximo. Aquí tienes la información actualizada:

  • El extremo (endpoint) para hacer ping al sitemap dejará de funcionar aproximadamente 6 meses después del 26 de junio de 2023.
  • Las solicitudes HTTP («pings») al extremo REST obsoleto generarán un error 404.
  • Google ha determinado que la mayoría de estos envíos no autenticados generan spam y ya no son útiles para el proceso de indexación.

En lugar de utilizar el método de ping, se recomienda:

  1. Utilizar Google Search Console para enviar y gestionar tus mapas del sitio.
  2. Incluir la URL de tu mapa del sitio en el archivo robots.txt de tu sitio web.

Si aún tienes código que utiliza el método de ping, como el siguiente ejemplo:

import urllib.request

url = "http://www.google.com/ping?sitemap=https://www.ejemplo.com/sitemap.xml"
response = urllib.request.urlopen(url)

Es recomendable que lo elimines o lo actualices para usar los métodos recomendados por Google.

Tip: Considera cómo eliminar redirecciones en tu sitemap para mejorar la eficiencia del rastreo. Las redirecciones en tu sitemap pueden desperdiciar el presupuesto de rastreo y ralentizar el proceso de indexación.

3. API de indexación de Google

La API de indexación de Google puede ser útil para mejorar las tasas de rastreo de ciertas páginas, pero generalmente no es una solución efectiva para conseguir que cualquier tipo de contenido sea indexado. Esta API está diseñada específicamente para casos en los que tu sitio web contiene datos estructurados de tipo JobPosting o BroadcastEvent incrustado en un VideoObject. Utilizarla fuera de estos escenarios puede ir en contra de las políticas de Google y podría acarrear consecuencias no deseadas.

Para usar esta API, primero debes configurar un proyecto en Google Cloud Console, crear una credencial de cuenta de servicio y habilitar la API de indexación. Luego, puedes utilizar el siguiente código actualizado para realizar la solicitud de indexación:

import json
from google.oauth2 import service_account
from google.auth.transport.requests import Request
import requests

SCOPES = ["https://www.googleapis.com/auth/indexing"]
ENDPOINT = "https://indexing.googleapis.com/v3/urlNotifications:publish"
content = {'url': 'https://www.ejemplo.com/nueva-pagina/', 'type': "URL_UPDATED"}

credentials = service_account.Credentials.from_service_account_file(
    "path_to_your_credentials.json", scopes=SCOPES)
credentials.refresh(Request())

headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + credentials.token
}

response = requests.post(ENDPOINT, headers=headers, json=content)
print(response.status_code)
print(response.text)

Tip: Si tu sitio web utiliza JavaScript para renderizar contenido, asegúrate de entender cómo Google indexa JavaScript. Esto puede afectar significativamente la forma en la que tus páginas son rastreadas e indexadas. Utiliza herramientas como el «Mobile-Friendly Test» de Google o la herramienta de inspección de URL en Google Search Console para verificar cómo Google ve tu contenido renderizado con JavaScript.

Para Bing

Bing ofrece una característica muy conveniente en Bing Webmaster Tools que permite solicitar la indexación de hasta 10,000 URLs por día en la mayoría de los casos. Además, Bing cuenta con una API de indexación que es más flexible y fácil de usar en comparación con la de Google.

Para utilizar la API de indexación de Bing con Python, se recomienda utilizar el siguiente código actualizado:

import requests
import json

API_KEY = 'tu_clave_api'
SITE_URL = 'https://www.ejemplo.com'
URLS_TO_INDEX = ['https://www.ejemplo.com/nueva-pagina/']

url = f'https://ssl.bing.com/webmaster/api.svc/json/SubmitUrlbatch?apikey={API_KEY}'

# Crear el payload de la solicitud
payload = {
    "siteUrl": SITE_URL,
    "urlList": URLS_TO_INDEX
}

headers = {'Content-type': 'application/json; charset=utf-8'}

# Realizar la solicitud POST
response = requests.post(url, data=json.dumps(payload), headers=headers)

# Imprimir el código de estado y el texto de la respuesta
print(response.status_code)
print(response.text)

Tip: No subestimes la importancia de Bing en tu estrategia SEO. Aunque Google domina el mercado de búsquedas, Bing puede ser una fuente significativa de tráfico, especialmente en ciertos nichos y regiones geográficas. Asegúrate de optimizar tu contenido para ambas plataformas y monitorear el rendimiento en Bing Webmaster Tools para aprovechar todas las oportunidades de visiibilidad.

Análisis, creación y carga de sitemaps

Los sitemaps son fundamentales para proporcionar a los motores de búsqueda las URLs que queremos que rastreen. Con Python, podemos abordar tres aspectos principales relacionados con los sitemaps: análisis, creación y carga en Google Search Console.

Análisis de sitemaps con Python

Podemos usar la biblioteca advertools para importar sitemaps a DataFrames, lo cual nos permite analizar fácilmente las URLs:

# Instala advertools con: pip install advertools
from advertools import sitemap_to_df

df = sitemap_to_df('https://ejemplo.com/robots.txt', recursive=False)

Creación de sitemaps con Python

Podemos usar Python para generar sitemaps de forma programática, lo cual es útil para sitios web muy dinámicos:

from xml.etree.ElementTree import Element, SubElement, tostring
from xml.dom import minidom

def create_sitemap(urls):
    urlset = Element('urlset')
    urlset.set('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9')
    
    for url in urls:
        url_element = SubElement(urlset, 'url')
        loc = SubElement(url_element, 'loc')
        loc.text = url
    
    xml_string = minidom.parseString(tostring(urlset)).toprettyxml(indent='  ')
    
    with open('sitemap.xml', 'w') as f:
        f.write(xml_string)

# Lista de URLs de ejemplo
def obtener_urls_dinamicamente(sitio_url):
    import requests
    from bs4 import BeautifulSoup

    response = requests.get(sitio_url)
    soup = BeautifulSoup(response.content, 'html.parser')
    return [link.get('href') for link in soup.find_all('a', href=True) if link.get('href').startswith(sitio_url)]

urls = obtener_urls_dinamicamente('https://www.ejemplo.com')
create_sitemap(urls)

Carga y eliminación de sitemaps en Google Search Console

Google Search Console tiene una API que permite cargar y eliminar sitemaps de forma programática. Asegúrate de autenticarte utilizando OAuth 2.0 antes de interactuar con la API. Aquí un ejemplo de cómo cargar un sitemap:

from google.oauth2 import service_account
from googleapiclient.discovery import build

# Configurar la autenticación y las credenciales
credentials = service_account.Credentials.from_service_account_file('ruta_a_tu_credencial.json', scopes=['https://www.googleapis.com/auth/webmasters'])
service = build('webmasters', 'v3', credentials=credentials)

# Cargar el sitemap
WEBSITE = 'https://www.ejemplo.com'
SITEMAP_PATH = 'https://www.ejemplo.com/sitemap.xml'
service.sitemaps().submit(siteUrl=WEBSITE, feedpath=SITEMAP_PATH).execute()

Análisis de enlaces internos y oportunidades

Tener una estructura de enlaces internos adecuada es crucial para facilitar a los bots de los motores de búsqueda el rastreo de tu sitio web. Algunos de los principales problemas que se encuentran al auditar sitios web con configuraciones técnicas sofisticadas son:

  • Enlaces introducidos con eventos on-click
  • Enlaces renderizados del lado del cliente
  • Pop-ups de inicio de sesión y/o verificación de edad
  • Uso excesivo del atributo nofollow
  • Páginas con noindex pero con follow

Con Python, podemos analizar nuestra estructura de enlaces internos y encontrar nuevas oportunidades de enlazado interno de manera masiva.

Extracción de enlaces internos con Python

Podemos utilizar bibliotecas como requests y BeautifulSoup para rastrear un sitio web y extraer los enlaces internos.

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import re

start_url = 'https://www.tusitioweb.com'
domain = urlparse(start_url).netloc
visited = set()
to_visit = [start_url]
internal_links = set()

while to_visit:
    url = to_visit.pop(0)
    if url in visited:
        continue
    visited.add(url)
    try:
        response = requests.get(url)
    except requests.exceptions.RequestException:
        continue
    soup = BeautifulSoup(response.text, 'html.parser')
    for link in soup.find_all('a', href=True):
        href = link.get('href')
        href = urljoin(url, href)
        parsed_href = urlparse(href)
        if parsed_href.netloc == domain:
            internal_links.add(href)
            if href not in visited:
                to_visit.append(href)

Este script rastrea tu sitio web comenzando desde la URL inicial y almacena todos los enlaces internos en el conjunto internal_links.

Identificación de enlaces problemáticos

Enlaces con eventos on-click

Los enlaces que dependen de eventos on-click pueden no ser rastreados por los bots. Podemos buscarlos en el código fuente.

for script in soup.find_all(onclick=True):
    print(f"Elemento con onclick encontrado en {url}: {script}")

Enlaces renderizados del lado del cliente

Para detectar enlaces que se cargan dinámicamente con JavaScript, podemos usar una herramienta como Selenium que permite renderizar páginas completas.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)

driver.get(url)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')

Detección de atributos nofollow

Podemos identificar enlaces que tienen el atributo rel="nofollow".

for link in soup.find_all('a', href=True):
    rel = link.get('rel')
    if rel and 'nofollow' in rel:
        print(f"Enlace nofollow encontrado en {url}: {link.get('href')}")

Páginas con noindex pero con follow

Podemos verificar si una página tiene la etiqueta meta noindex y follow.

meta_robots = soup.find('meta', attrs={'name': 'robots'})
if meta_robots:
    content = meta_robots.get('content')
    if 'noindex' in content and 'follow' in content:
        print(f"Página con noindex, follow en {url}")

Encontrar oportunidades de enlazado interno

Podemos analizar el contenido de nuestras páginas para encontrar palabras clave y crear enlaces internos relevantes.

import nltk
from nltk.corpus import stopwords
nltk.download('stopwords')
nltk.download('punkt')

keywords = ['palabra', 'clave']

for url in visited:
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    text = soup.get_text()
    tokens = nltk.word_tokenize(text)
    tokens = [word.lower() for word in tokens if word.isalpha()]
    filtered_words = [word for word in tokens if word not in stopwords.words('spanish')]
    for keyword in keywords:
        if keyword in filtered_words:
            print(f"Oportunidad de enlazado interno en {url} para la palabra clave '{keyword}'")

Este script busca oportunidades de enlazado interno identificando páginas que contienen ciertas palabras clave.

Tip: Implementa una estrategia de enlazado interno basada en la relevancia temática y la importancia de las páginas, no solo en la estructura de navegación. Esto puede ayudar a distribuir la autoridad de enlace de manera más efectiva en tu sitio.

Velocidad del sitio web, errores 5xx y páginas de error leves

Como se indica en la documentación de Google sobre lo que significa el presupuesto de rastreo para Googlebot, hacer que tu sitio sea más rápido mejora la experiencia del usuario y aumenta la tasa de rastreo. Por otro lado, también hay otros factores que pueden afectar el presupuesto de rastreo, como las páginas de error leves, el contenido de baja calidad y el contenido duplicado en el sitio.

Velocidad de página y Python

Podemos utilizar la API de Page Speed Insights para analizar cómo está funcionando nuestro sitio web en términos de velocidad de página y obtener datos sobre muchas métricas diferentes de velocidad de página (casi 50) además de Core Web Vitals.

import urllib.request, json

url = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=tu_URL&strategy=mobile&locale=es&key=tu_clave_API"
response = urllib.request.urlopen(url)
data = json.loads(response.read())

Tip: No te obsesiones con obtener una puntuación perfecta en las herramientas de velocidad. Enfócate en mejorar la experiencia real del usuario y en optimizar las métricas que tienen un impacto directo en la conversión y el engagement.

Extracción de errores 5xx y otros códigos de respuesta con Python

Los errores de código de respuesta 5xx pueden ser indicativos de que tu servidor no es lo suficientemente rápido para hacer frente a todas las solicitudes que recibe. Esto puede tener un impacto muy negativo en tu tasa de rastreo y también puede dañar la experiencia del usuario.

import requests

def check_status_code(url):
    try:
        response = requests.get(url)
        return response.status_code
    except requests.RequestException as e:
        return str(e)

urls = ['https://www.ejemplo.com', 'https://www.ejemplo.com/pagina1', 'https://www.ejemplo.com/pagina2']

for url in urls:
    print(f"{url}: {check_status_code(url)}")

Tip: Implementa un sistema de monitoreo proactivo para detectar y resolver rápidamente los errores del servidor. Herramientas como Pingdom o New Relic pueden ser muy útiles para esto.

Extracción de páginas de error leves con Python

Podemos automatizar la extracción del informe de cobertura de Google Search Console para compilar en una sola pestaña de Excel todas las URLs que Google Search Console proporciona como erróneas, válidas con advertencias, válidas y excluidas. Aquí tienes un ejemplo de cómo podrías hacerlo:

from googleapiclient.discovery import build
import pandas as pd

# Configura el servicio de Search Console
service = build('searchconsole', 'v1', credentials=credentials)

# Obtén el informe de cobertura
site_url = 'https://www.ejemplo.com/'
request = {
    'startDate': '2023-01-01',
    'endDate': '2023-12-31',
    'dimensions': ['page'],
    'rowLimit': 25000
}

response = service.searchanalytics().query(siteUrl=site_url, body=request).execute()

# Procesa los resultados
rows = response['rows']
df = pd.DataFrame(rows)
df.columns = ['url', 'clicks', 'impressions', 'ctr', 'position']

# Guarda los resultados en un archivo Excel
df.to_excel('informe_cobertura.xlsx', index=False)

Tip: Presta especial atención a las páginas que Google marca como «Válidas con advertencias». Estas páginas pueden tener problemas menores que, si se corrigen, podrían mejorar significativamente su rendimiento en los resultados de búsqueda.

Análisis de archivos de logs con Python

Además de los datos disponibles en el informe de estadísticas de rastreo de Google Search Console, también puedes analizar tus propios archivos de registro utilizando Python para obtener mucha más información sobre cómo los bots de los motores de búsqueda están rastreando tu sitio web.

Aquí tienes un ejemplo de cómo podrías analizar un archivo de registro de servidor:

import pandas as pd
import re

# Función para parsear una línea de log
def parse_log_line(line):
    pattern = r'(\S+) (\S+) (\S+) \[(.*?)\] "(.*?)" (\d+) (\d+) "(.*?)" "(.*?)"'
    match = re.match(pattern, line)
    if match:
        return {
            'ip': match.group(1),
            'timestamp': match.group(4),
            'request': match.group(5),
            'status': match.group(6),
            'size': match.group(7),
            'referer': match.group(8),
            'user_agent': match.group(9)
        }
    return None

# Lee el archivo de log
with open('access.log', 'r') as f:
    logs = [parse_log_line(line) for line in f if parse_log_line(line)]

# Convierte a DataFrame
df = pd.DataFrame(logs)

# Filtra solo las solicitudes de Googlebot
googlebot_requests = df[df['user_agent'].str.contains('Googlebot', case=False)]

# Analiza las páginas más rastreadas
most_crawled = googlebot_requests['request'].value_counts().head(10)
print("Páginas más rastreadas por Googlebot:")
print(most_crawled)

Tip : Los archivos de logs pueden revelar patrones de rastreo que no son evidentes en otras herramientas. Por ejemplo, puedes identificar si Googlebot está gastando demasiado tiempo en páginas poco importantes o si está teniendo problemas para acceder a ciertas secciones de tu sitio.

Implementación de técnicas avanzadas de SEO

Además de las técnicas mencionadas anteriormente, hay varias estrategias avanzadas que puedes implementar para mejorar aún más tu SEO técnico:

1. Optimización de JavaScript para SEO

Como mencionamos anteriormente, es crucial entender cómo Google indexa JavaScript. Algunas estrategias clave incluyen:

  • Utilizar el renderizado del lado del servidor (SSR) cuando sea posible.
  • Minimizar el uso de JavaScript para contenido crítico para SEO.
  • Utilizar la API de Google Search Console para pruebas de renderizado.

2. Implementación de datos estructurados

Los datos estructurados pueden mejorar significativamente cómo aparecen tus páginas en los resultados de búsqueda. Puedes usar Python para generar y validar automáticamente tus datos estructurados:

import json
from jsonschema import validate

# Ejemplo de datos estructurados para un artículo
article_schema = {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "Título del artículo",
    "author": {
        "@type": "Person",
        "name": "Nombre del autor"
    },
    "datePublished": "2023-06-12",
    "image": "https://ejemplo.com/imagen.jpg"
}

# Validar el esquema
schema = json.loads(open('article_schema.json').read())
validate(instance=article_schema, schema=schema)

print(json.dumps(article_schema, indent=2))

Tip: Mantente al día con los nuevos tipos de datos estructurados que Google admite. A menudo, ser de los primeros en implementar un nuevo tipo de dato estructurado puede darte una ventaja competitiva en los SERPs.

3. Optimización de Core Web Vitals

Los Core Web Vitals son un conjunto de métricas que Google utiliza para evaluar la experiencia del usuario en tu sitio. Puedes usar Python para monitorear estas métricas:

import requests

url = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed"
params = {
    "url": "https://www.ejemplo.com",
    "strategy": "mobile",
    "key": "TU_API_KEY"
}

response = requests.get(url, params=params)
data = response.json()

lcp = data['lighthouseResult']['audits']['largest-contentful-paint']['displayValue']
fid = data['lighthouseResult']['audits']['max-potential-fid']['displayValue']
cls = data['lighthouseResult']['audits']['cumulative-layout-shift']['displayValue']

print(f"LCP: {lcp}")
print(f"FID: {fid}")
print(f"CLS: {cls}")

Tip: No te enfoques solo en los números. Las mejoras en los Core Web Vitals deben traducirse en una mejor experiencia real del usuario. Usa herramientas de análisis de comportamiento del usuario para verificar que las mejoras en las métricas se correlacionan con mejoras en la interacción del usuario.

En constante evolución

Aquí tienes 7 tips de SEO que puedes hacer tú mismo y que complementan perfectamente las técnicas más avanzadas que hemos discutido en este artículo. Recuerda que el SEO es tanto un arte como una ciencia, y la combinación de técnicas básicas bien ejecutadas con estrategias avanzadas es lo que realmente puede marcar la diferencia.

Es crucial mantenerse al día con las últimas actualizaciones y cambios en los algoritmos de los motores de búsqueda. Lo que funciona hoy puede no ser tan efectivo mañana. Por eso, la experimentación constante, el análisis de datos y la adaptación son fundamentales para el éxito a largo plazo en SEO.

Daniel Pajuelo
Daniel Pajuelo es ingeniero informático y SEO Senior, actualmente trabajando en Guruwalk e impartiendo clases en BIG School (antes BIGSEO Academy). Ver más
Categorías SEO

Continua leyendo

ChatGPT para Keyword Research

Descubre cómo combinar el poder de la IA con herramientas tradicionales como Semrush y Ahrefs para descubrir oportunidades SEO únicas. Con ejemplos de prompts y casos reales.

Cómo encontrar enlaces rotos con Python

En este artículo, te explico cómo utilizar scripts Python para analizar el SEO y detectar enlaces rotos en tu sitio web. ¡Vamos al grano!

Cómo encontrar los Backlinks de un sitio con Python

En este artículo, te explico cómo encontrar los backlinks existentes y distinguir su calidad, diferenciando entre enlaces dofollow y nofollow utilizando código Python.