Obtener el enlace interno optimizado es importante si le importa que las páginas de su sitio tengan suficiente autoridad para clasificar sus palabras clave objetivo. Por vinculación interna nos referimos a páginas de su sitio web que 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 PageRank de Google algoritmo.
Hoy, estamos explorando un enfoque basado en datos para mejorar el enlace interno de un sitio web con el fin de lograr un SEO técnico de sitios más eficaz. Eso es para garantizar que la distribución de la autoridad de dominio interno 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 solo un 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 la profundidad de su sitio en particular.
Anuncio publicitario
Continuar leyendo a continuación
Comenzamos importando las bibliotecas y los datos, limpiando los nombres de las columnas antes de obtener una vista previa de ellos:
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 de Sitebulb. Hay más de 8.000 filas y no todas serán exclusivas del dominio, ya que también incluirán 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.
Anuncio publicitario
Continuar leyendo a continuación
Sin embargo, antes de ingresar 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
Entonces, 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 manipular datos) ordena los niveles del sitio por dígitos.
Eso es porque los niveles del sitio son en esta etapa 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 direcciones URL indexables y seleccionar las columnas relevantes, ahora tenemos un marco de datos más optimizado (piense en la versión Pandas de una pestaña de hoja de cálculo).
Explorando la distribución de enlaces internos
Ahora estamos listos para visualizar los datos y tener una idea de cómo vínculos internos se distribuyen globalmente 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 el enlace interno sería una oportunidad significativa para mejorar el SEO aquí.
Consigamos algunas estadísticas a nivel del sitio.
Anuncio publicitario
Continuar leyendo a continuación
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, incluida la media (media) y la mediana (cuantil del 50%).
Esto es junto con la variación dentro del nivel del sitio (std para la desviación estándar), que nos dice qué tan cerca del promedio están las páginas dentro del nivel del sitio; es decir, qué tan consistente es la distribución del enlace interno con el promedio.
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), varía de 0 a 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 sin rodeos vinculadas reciben la mayor parte de los enlaces.
Anuncio publicitario
Continuar leyendo a continuación
Con las escalas como están, no tenemos mucha visión de 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 dos primeros niveles del sitio y el sitio restante, esto es indicativo de una distribución sesgada.
Anuncio publicitario
Continuar leyendo a continuación
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 visualizaremos:
# 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
A partir de lo anterior, la distribución parece mucho menos sesgada, ya que los cuadros (rangos intercuartílicos) tienen un cambio escalonado más gradual desde el nivel del sitio hasta el nivel del sitio.
Esto nos prepara muy bien para analizar los datos antes de diagnosticar qué URL no están optimizadas desde el punto de vista del enlace interno.
Anuncio publicitario
Continuar leyendo a continuación
Cuantificando los problemas
El siguiente código calculará el 35º cuantil inferior (término de ciencia de datos para percentil) para la profundidad de cada 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 insuficientes en cada nivel de sitio.
Ahora que tenemos la tabla, los fusionaremos con el conjunto de datos principal para determinar si la URL fila por fila está subvinculada o no.
Anuncio publicitario
Continuar leyendo a continuación
# 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 subenlazada debajo de la columna » sd_int_uidx ‘como un 1.
Esto nos coloca en posición de sumar la cantidad de páginas de sitios con enlaces insuficientes 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 que están subenlazadas.
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 del Mapa del sitio XML URL, la distribución de URL con enlaces insuficientes parece normal, como lo indica la forma de campana cercana. La mayoría de las URL con enlaces insuficientes se encuentran en los niveles de sitio 3 y 4.
Anuncio publicitario
Continuar leyendo a continuación
Exportación de la lista de URL subenlazadas
Ahora que tenemos un control sobre las URL con vínculos 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.
Anuncio publicitario
Continuar leyendo a continuación
Luego procedimos a cuantificar el alcance del problema de los vínculos subyacentes tanto numérica como visualmente antes de exportar los resultados para las 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 enlaces internos incluyen y obviamente no se limitan a:
- Autoridad de nivel de página fuera del sitio.
- Relevancia del texto de anclaje.
- Intención de búsqueda.
- Buscar el recorrido del usuario.
¿Qué aspectos le gustaría ver cubiertos?
Deje un comentario a continuación.
Más recursos:
Anuncio publicitario
Continuar leyendo a continuación
Imagen destacada: Shutterstock / Optimarc
Consultar el artículo en la publicación original