Script SEO: Un Tinder para tus URLS
05/04/2023 por gabriel.noguera

Front.id

Esto es lo que ha creado Greg Bernhardt con este script para #seo puedes automatizar el proceso de hacer match entre URLs que tienen una coincidencia de entidades relacionandolo con el propio #GoogleKnowledgeGraph a través de su API.

Si tienes un blog desordenado o aparentemente lleno de artículos aleatorios y tienes la tarea de enlazarlos internamente de forma inteligente, esto es fundamental.

Artículos con altas coincidencias son más propensos a ser buenos para la vinculación interna.

Te detallo los pasos de este script en Python:

1. Instalamos las dependencias y librerías necesarias

import requests
import pandas as pd
import nltk
nltk.download('punkt')
from nltk.util import ngrams
from nltk.corpus import stopwords
nltk.download('stopwords')
nltk.download('averaged_perceptron_tagger')
import string
from collections import Counter
from bs4 import BeautifulSoup
import json

2. El primer paso es obtener su URL CSV para las páginas que desea procesar. Debes crear uno con el listado de URLS en una columna que se titule "Address" y subirlo a este entorno en la carpeta content Yo no ejecutaría este script en una lista de URLs sin limpiar. Tampoco lo ejecutaría en miles de páginas o el procesamiento puede tardar mucho tiempo. La lista de URLs debe ser sólo sus páginas de contenido, tales como su blog, las páginas tienen que tener la misma plantilla. A continuación creamos también un pequeño filtro de puntuación que puedes añadir para eliminarlo durante el procesamiento y creamos dos listas para más adelante.

df = pd.read_csv("urls.csv")
urls = df["Address"].tolist()
punct = ["’","”"]
ngram_count = []
ngram_dedupe = []

3. A continuación, creamos nuestra función N-gram. Esta función utilizará la biblioteca NLTK para dividir el texto de una página web en combinaciones sucesivas de N palabras. La variable num es N. Por tanto, si establecemos el valor de Num en 1, generaremos 1-gramas, si es 2, 2-gramas, etc.

def extract_ngrams(data, num):
  n_grams = ngrams(nltk.word_tokenize(data), num)
  gram_list = [ ' '.join(grams) for grams in n_grams]
  return gram_list

4. Ahora configuramos la función para que envíe cada n-grama de nuestra lista a la API Knowledge Graph de Google para determinar si se trata de una entidad. Esto nos ayuda a limpiar la lista de n-gramas y a asegurarnos de que coinciden con palabras que son de actualidad y contextualmente importantes. Puedes crear fácilmente una API gratuita aquí si aún no tienes una. Todo lo que ocurre aquí es que hacemos un bucle con nuestra lista de n-gramas y enviamos cada uno de ellos a la API. Si obtenemos una respuesta positiva, sabemos que se trata de una entidad y la añadimos a una nueva lista que utilizaremos más adelante. Si no es una entidad, la descartamos.

def kg(keywords):

  kg_entities = []
  apikey='INSERT YOUR API'

  for x in keywords:
    url = f'https://kgsearch.googleapis.com/v1/entities:search?query={x}&key='+apikey+'&limit=1&indent=True'
    payload = {}
    headers= {}
    response = requests.request("GET", url, headers=headers, data = payload)
    data = json.loads(response.text)

    try:
      getlabel = data['itemListElement'][0]['result']['@type']
      hit = "yes"
      kg_entities.append(x)
    except:
      hit = "no"

  return kg_entities

5. Aquí es donde hacemos un bucle a través de cada URL, raspamos el HTML y luego lo procesamos.

for x in urls:
  res = requests.get(x)
  html_page = res.text

  # CHUNK 1
  soup = BeautifulSoup(html_page, 'html.parser')
  for script in soup(["script", "noscript","nav","style","input","meta","label","header","footer","aside","h1","a","table","button"]):
    script.decompose()
  text = soup.find("div",{"class":"the_content"}) #edit this to match your template
  page_text = (text.get_text()).lower()
  page_text = page_text.strip().replace("  ","")
  text_content1 = "".join([s for s in page_text.splitlines(True) if s.strip("\r\n")])

  # CHUNK 2
  keywords = extract_ngrams(text_content1, 1)
  keywords = [x.lower() for x in keywords if x not in string.punctuation]
  keywords = [x for x in keywords if ":" not in x]
  stop_words = set(stopwords.words('english'))
  keywords = [x for x in keywords if not x in stop_words]
  keywords = [x for x in keywords if not x in punct]

  # CHUNK 3
  keywords_dedupe = list(set(keywords))
  tokens = [x for x in keywords_dedupe if isinstance(x, str)]
  keywords = nltk.pos_tag(tokens)
  keywords = [x for x in keywords if x[1] not in ['CD','RB','JJS','IN','MD','WDT','DT','RBR','VBZ','WP']]
  keywords = [x[0] for x in keywords]

  # CHUNK 4
  attach_url = x
  keywords.append(attach_url)
  ngram_dedupe.append(keywords)

6. Ahora creamos nuestro marco de datos vacío donde almacenaremos nuestras oportunidades de enlaces internos. Luego simplemente comparamos cada URL con cada una de las otras URL y evitamos comparar contra sí misma. A continuación, añadimos los resultados de cada comparación a un objeto diccionario y lo añadimos al marco de datos que creamos anteriormente. El recuento de coincidencias se almacena en ngram_matchs.

d = {'from url': [], 'to url': [], 'ngram match count':[]}
df2 = pd.DataFrame(data=d)

for x in ngram_dedupe:
  item_url = x[-1]
  for y in ngram_dedupe:
    item_url2 = y[-1]
    if item_url != item_url2:
      ngram_matchs = set(x).intersection(y)
      new_dict = {"from url":item_url,"to url":item_url2,"ngram match count":len(ngram_matchs)}
      df2 = df2.append(new_dict, ignore_index=True)

7. Sólo queda imprimir los resultados y, opcionalmente, guardarlos como CSV. Cuanto mayor sea la coincidencia, más probable es que exista una oportunidad de interrelación temática entre las dos páginas.

df2 = df2.sort_values(by=['ngram match count'],ascending=False)
df2.to_csv('ngram_interlinking.csv')
df2

 

Te dejo el link al artículo original: https://importsem.com/find-interlinking-opps-via-entity-n-gram-matches-using-python/

Lo he maquetado en #Colab y a continuación es vuestro también: https://colab.research.google.com/drive/1ksJBp3nx8rFg0QSx6v6xzqwY7TrYMmbj?usp=sharing

;)

Agregar nuevo comentario

El contenido de este campo se mantiene privado y no se mostrará públicamente.

HTML Restringido

  • Etiquetas HTML permitidas: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Las líneas y los párrafos se rompen automáticamente.
  • Las direcciones de las páginas web y las direcciones de correo electrónico se convierten en enlaces automáticamente.