Conozca el enfoque basado en datos para mejorar los enlaces internos de un sitio web con el fin de lograr un SEO técnico más efectivo.
Optimizar los enlaces internos es importante si le importa que las páginas de su sitio tengan suficiente autoridad para clasificar sus palabras clave objetivo.. Por enlace interno lo que queremos decir es que las páginas de su sitio web reciben enlaces de otras páginas.
Esto es importante porque es la base por la cual Google y otras búsquedas calculan la importancia de la página en relación con otras páginas de su sitio web.
También afecta la probabilidad de que un usuario descubra contenido en su sitio.. El descubrimiento de contenido es la base del algoritmo Google PageRank.
Hoy, estamos explorando un enfoque basado en datos para mejorar los enlaces internos de un sitio web con el fin de lograr un SEO técnico más efectivo.. Eso es para garantizar que la distribución de la autoridad de dominio interna se optimice de acuerdo con la estructura del sitio.
Mejora de las estructuras de enlaces internos con ciencia de datos
Nuestro enfoque basado en datos se centrará en un solo aspecto de la optimización de la arquitectura de enlaces internos, que es modelar la distribución de enlaces internos por profundidad del sitio y luego apuntar a las páginas que carecen de enlaces para su profundidad de sitio particular.
Comenzamos importando las bibliotecas y los datos, limpiando los nombres de las columnas antes de obtener una vista previa:
import pandas as pd import numpy as np site_name = 'ON24' site_filename = 'on24' website = 'www.on24.com' # import Crawl Data crawl_data = pd.read_csv('data/'+ site_filename + '_crawl.csv') crawl_data.columns = crawl_data.columns.str.replace(' ','_') crawl_data.columns = crawl_data.columns.str.replace('.','') crawl_data.columns = crawl_data.columns.str.replace('(','') crawl_data.columns = crawl_data.columns.str.replace(')','') crawl_data.columns = map(str.lower, crawl_data.columns) print(crawl_data.shape) print(crawl_data.dtypes) Crawl_data (8611, 104) url object base_url object crawl_depth object crawl_status object host object ... redirect_type object redirect_url object redirect_url_status object redirect_url_status_code object unnamed:_103 float64 Length: 104, dtype: object
Lo anterior muestra una vista previa de los datos importados desde la aplicación de rastreo de escritorio Sitebulb. Hay más de 8000 filas y no todas serán exclusivas del dominio, ya que también incluirá URL de recursos y URL de enlaces salientes externos.
También tenemos más de 100 columnas que son superfluas para los requisitos, por lo que se requerirá alguna selección de columnas.
Sin embargo, antes de entrar en eso, queremos ver rápidamente cuántos niveles de sitio hay:
crawl_depth 0 1 1 70 10 5 11 1 12 1 13 2 14 1 2 303 3 378 4 347 5 253 6 194 7 96 8 33 9 19 Not Set 2351 dtype: int64
De lo anterior, podemos ver que hay 14 niveles de sitio y la mayoría de estos no se encuentran en la arquitectura del sitio, sino en el mapa del sitio XML.
Puede notar que Pandas (el paquete de Python para el manejo de datos) ordena los niveles del sitio por dígito.
Esto se debe a que, en esta etapa, los niveles del sitio son cadenas de caracteres en lugar de numéricos.. Esto se ajustará en el código posterior, ya que afectará la visualización de datos («a saber»).
Ahora, filtraremos filas y seleccionaremos columnas.
# Filter for redirected and live links
redir_live_urls = crawl_data[['url', 'crawl_depth', 'http_status_code', 'indexable_status', 'no_internal_links_to_url', 'host', 'title']] redir_live_urls = redir_live_urls.loc[redir_live_urls.http_status_code.str.startswith(('2'), na=False)] redir_live_urls['crawl_depth'] = redir_live_urls['crawl_depth'].astype('category') redir_live_urls['crawl_depth'] = redir_live_urls['crawl_depth'].cat.reorder_categories(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', 'Not Set', ]) redir_live_urls = redir_live_urls.loc[redir_live_urls.host == website] del redir_live_urls['host'] print(redir_live_urls.shape) Redir_live_urls (4055, 6)
Al filtrar filas para URL indexables y seleccionar las columnas relevantes, ahora tenemos un marco de datos más optimizado (piense en la versión de Pandas de una pestaña de hoja de cálculo).
Explorando la distribución de enlaces internos
Ahora estamos listos para ver los datos y tener una idea de cómo se distribuyen los enlaces internos en general y por profundidad del sitio.
from plotnine import * import matplotlib.pyplot as plt pd.set_option('display.max_colwidth', None) %matplotlib inline # Distribution of internal links to URL by site level ove_intlink_dist_plt = (ggplot(redir_live_urls, aes(x = 'no_internal_links_to_url')) + geom_histogram(fill = 'blue', alpha = 0.6, bins = 7) + labs(y = '# Internal Links to URL') + theme_classic() + theme(legend_position = 'none') ) ove_intlink_dist_plt
De lo anterior podemos ver abrumadoramente que la mayoría de las páginas no tienen enlaces, por lo que mejorar los enlaces internos sería una oportunidad importante para mejorar el SEO aquí.
Veamos algunas estadísticas a nivel del sitio.
crawl_depth 0 1 1 70 10 5 11 1 12 1 13 2 14 1 2 303 3 378 4 347 5 253 6 194 7 96 8 33 9 19 Not Set 2351 dtype: int64
La tabla anterior muestra la distribución aproximada de los enlaces internos por nivel de sitio, incluido el promedio (media) y la mediana (50% del cuantil).
Esto es junto con la variación dentro del nivel del sitio (desviación estándar estándar), que nos dice qué tan cerca del promedio están las páginas dentro del nivel del sitio;
De lo anterior podemos suponer que el promedio por nivel de sitio, con la excepción de la página de inicio (profundidad de rastreo 0) y las páginas de primer nivel (profundidad de rastreo 1), oscila entre 0 y 4 por URL.
Para un enfoque más visual:
# Distribution of internal links to URL by site level intlink_dist_plt = (ggplot(redir_live_urls, aes(x = 'crawl_depth', y = 'no_internal_links_to_url')) + geom_boxplot(fill = 'blue', alpha = 0.8) + labs(y = '# Internal Links to URL', x = 'Site Level') + theme_classic() + theme(legend_position = 'none') ) intlink_dist_plt.save(filename = 'images/1_intlink_dist_plt.png', height=5, width=5, units = 'in', dpi=1000) intlink_dist_plt
El gráfico anterior confirma nuestros comentarios anteriores de que la página de inicio y las páginas vinculadas directamente desde ella reciben la mayor parte de los enlaces.
Con las escalas como están, no tenemos mucha vista sobre la distribución de los niveles inferiores.. Enmendaremos esto tomando un logaritmo del eje y:
# Distribution of internal links to URL by site level from mizani.formatters import comma_format intlink_dist_plt = (ggplot(redir_live_urls, aes(x = 'crawl_depth', y = 'no_internal_links_to_url')) + geom_boxplot(fill = 'blue', alpha = 0.8) + labs(y = '# Internal Links to URL', x = 'Site Level') + scale_y_log10(labels = comma_format()) + theme_classic() + theme(legend_position = 'none') ) intlink_dist_plt.save(filename = 'images/1_log_intlink_dist_plt.png', height=5, width=5, units = 'in', dpi=1000) intlink_dist_plt
Lo anterior muestra la misma distribución de los enlaces con la vista logarítmica, lo que nos ayuda a confirmar los promedios de distribución para los niveles inferiores.. Esto es mucho más fácil de visualizar.
Dada la disparidad entre los primeros dos niveles del sitio y el resto del sitio, esto es indicativo de una distribución sesgada.
Como resultado, tomaré un logaritmo de los enlaces internos, lo que ayudará a normalizar la distribución.
Ahora tenemos el número normalizado de enlaces, que vamos a visualizar:
# Distribution of internal links to URL by site level intlink_dist_plt = (ggplot(redir_live_urls, aes(x = 'crawl_depth', y = 'log_intlinks')) + geom_boxplot(fill = 'blue', alpha = 0.8) + labs(y = '# Log Internal Links to URL', x = 'Site Level') + #scale_y_log10(labels = comma_format()) + theme_classic() + theme(legend_position = 'none') ) intlink_dist_plt
De lo anterior, la distribución parece mucho menos sesgada, ya que las cajas (rango intercuartílico) tienen un cambio de paso más gradual de nivel de sitio a nivel de sitio.
Esto nos prepara muy bien para analizar los datos antes de diagnosticar qué URL no están optimizadas desde el punto de vista de los enlaces internos.
Cuantificación de los problemas
El siguiente código calculará el cuantil 35 inferior (término de ciencia de datos para percentil) para cada profundidad del sitio.
# internal links in under/over indexing at site level # count of URLs under indexed for internal link counts quantiled_intlinks = redir_live_urls.groupby('crawl_depth').agg({'log_intlinks': [quantile_lower]}).reset_index() quantiled_intlinks = quantiled_intlinks.rename(columns = {'crawl_depth_': 'crawl_depth', 'log_intlinks_quantile_lower': 'sd_intlink_lowqua'}) quantiled_intlinks
Lo anterior muestra los cálculos.. Los números no tienen sentido para un profesional de SEO en esta etapa, ya que son arbitrarios y tienen el propósito de proporcionar un límite para las URL con enlaces inferiores en cada nivel del sitio.
Ahora que tenemos la tabla, los fusionaremos con el conjunto de datos principal para determinar si la URL fila por fila está enlazada o no.
# join quantiles to main df and then count redir_live_urls_underidx = redir_live_urls.merge(quantiled_intlinks, on = 'crawl_depth', how = 'left') redir_live_urls_underidx['sd_int_uidx'] = redir_live_urls_underidx.apply(sd_intlinkscount_underover, axis=1) redir_live_urls_underidx['sd_int_uidx'] = np.where(redir_live_urls_underidx['crawl_depth'] == 'Not Set', 1, redir_live_urls_underidx['sd_int_uidx']) redir_live_urls_underidx
Ahora tenemos un marco de datos con cada URL marcada como un enlace debajo de la columna «sd_int_uidx» como 1.
Esto nos coloca en posición de sumar la cantidad de páginas del sitio con enlaces inferiores por profundidad del sitio:
# Summarise int_udx by site level intlinks_agged = redir_live_urls_underidx.groupby('crawl_depth').agg({'sd_int_uidx': ['sum', 'count']}).reset_index() intlinks_agged = intlinks_agged.rename(columns = {'crawl_depth_': 'crawl_depth'}) intlinks_agged['sd_uidx_prop'] = intlinks_agged.sd_int_uidx_sum / intlinks_agged.sd_int_uidx_count * 100 print(intlinks_agged)
crawl_depth sd_int_uidx_sum sd_int_uidx_count sd_uidx_prop 0 0 0 1 0.000000 1 1 41 70 58.571429 2 2 66 303 21.782178 3 3 110 378 29.100529 4 4 109 347 31.412104 5 5 68 253 26.877470 6 6 63 194 32.474227 7 7 9 96 9.375000 8 8 6 33 18.181818 9 9 6 19 31.578947 10 10 0 5 0.000000 11 11 0 1 0.000000 12 12 0 1 0.000000 13 13 0 2 0.000000 14 14 0 1 0.000000 15 Not Set 2351 2351 100.000000
Ahora vemos que, a pesar de que la página de profundidad 1 del sitio tiene un número de enlaces por URL superior al promedio, todavía hay 41 páginas con enlaces inferiores.
Para ser más visual:
# plot the table depth_uidx_plt = (ggplot(intlinks_agged, aes(x = 'crawl_depth', y = 'sd_int_uidx_sum')) + geom_bar(stat = 'identity', fill = 'blue', alpha = 0.8) + labs(y = '# Under Linked URLs', x = 'Site Level') + scale_y_log10() + theme_classic() + theme(legend_position = 'none') ) depth_uidx_plt.save(filename = 'images/1_depth_uidx_plt.png', height=5, width=5, units = 'in', dpi=1000) depth_uidx_plt
Con la excepción de las URL del mapa del sitio XML, la distribución de las URL con enlaces subyacentes parece normal, como lo indica la forma de campana cercana.. La mayoría de las URL con enlaces inferiores se encuentran en los niveles de sitio 3 y 4.
Exportación de la lista de URL con enlaces inferiores
Ahora que tenemos un control sobre las URL con enlaces inferiores por nivel de sitio, podemos exportar los datos y encontrar soluciones creativas para cerrar las brechas en la profundidad del sitio, como se muestra a continuación.
# data dump of under performing backlinks underlinked_urls = redir_live_urls_underidx.loc[redir_live_urls_underidx.sd_int_uidx == 1] underlinked_urls = underlinked_urls.sort_values(['crawl_depth', 'no_internal_links_to_url']) underlinked_urls.to_csv('exports/underlinked_urls.csv') underlinked_urls
Otras técnicas de ciencia de datos para enlaces internos
Cubrimos brevemente la motivación para mejorar los enlaces internos de un sitio antes de explorar cómo se distribuyen los enlaces internos en el sitio por nivel de sitio.
Luego procedimos a cuantificar el alcance del problema de enlaces subyacentes tanto numérica como visualmente antes de exportar los resultados para recomendaciones.
Naturalmente, el nivel del sitio es solo un aspecto de los enlaces internos que se pueden explorar y analizar estadísticamente.
Otros aspectos que podrían aplicar técnicas de ciencia de datos a los enlaces internos incluyen y obviamente no se limitan a:
- Autoridad a nivel de página externa.
- Relevancia del texto ancla.
- Intención de búsqueda.
- Buscar recorrido del usuario.
¿Qué aspectos le gustaría ver cubiertos?
Por favor, deje un comentario a continuación.
Más recursos:
Imagen destacada: Shutterstock/Optimarc
Leer el articulo original en Search Engine Journal.