with soup how find_all example beautiful all python html parsing web-scraping beautifulsoup

python - how - Beautiful Soup-Encontrar el primer enlace en un artículo



python beautifulsoup findall (1)

Estoy creando una solución de Python para este problema, pero estoy teniendo problemas para superar algunos casos extremos.

El problema con el que me estoy metiendo surge para una página como esta, donde este enlace es el que debería extraerse, ya que es el primero fuera del paréntesis. Por el contrario, algunos artículos son como este donde el enlace aparece antes del primer paréntesis.

La manera en que estoy manejando estos casos actualmente es iterando inicialmente a través de los elementos y el texto en la etiqueta del primer párrafo (versión codificada) y verificando cuál se encuentra primero entre ''('' y <a> . Si <a> se encuentra primero (es decir, antes de que se haya alcanzado un paréntesis), simplemente tomo ese enlace. Si primero se encuentra un paréntesis, espero hasta que los paréntesis estén cerrados y luego tomo el siguiente ''

En efecto, estoy obteniendo el hijo directo del elemento del primer párrafo que podría hacerse con algo como:

soup = BeautifulSoup(response.content, "lxml") soup.select_one("#mw-content-text > p > a")

Lo que creo que funcionaría aquí es usar dicha instrucción select para encontrar el primer enlace en el prefijo desde el comienzo de th <p> hasta el primer paréntesis o (si no hay un enlace en el prefijo) buscar el enlace inmediatamente siguiendo el paréntesis de cierre usando algo similar a lo que estoy haciendo actualmente:

`findNext(''a'').attrs[''href'']`

Si se va a utilizar dicho enfoque, surgirán múltiples problemas, que incluyen: 1. Cómo obtener el prefijo hasta el primer paréntesis con solo los elementos secundarios directos del ''

¿Hay una manera simplificada de hacer esto? Si hay un mejor enfoque, ¿cuál sería?


Este problema me recuerda el algoritmo popular y el problema de las estructuras de datos cuando necesita verificar si los paréntesis u otros corchetes están equilibrados. Para este tipo de problemas, es conveniente usar una estructura de datos de pila .

Entonces, en este caso, presionaremos para apilar si hay un paréntesis de apertura y saldrá de él si hay uno de cierre . El enlace válido para nosotros sería uno cuando la pila está vacía :

import requests from bs4 import BeautifulSoup, NavigableString, Tag urls = [ "https://en.wikipedia.org/wiki/Modern_Greek", "https://en.wikipedia.org/wiki/Diglossia" ] with requests.Session() as session: for url in urls: response = session.get(url) soup = BeautifulSoup(response.content, "html.parser") stack = [] for child in soup.select_one("#mw-content-text > p").children: if isinstance(child, NavigableString): if "(" in child: stack.append("(") if ")" in child: stack.pop() if isinstance(child, Tag) and child.name == "a" and not stack: print(child.get_text()) break

Imprime dialects para la página "Griega moderna" y la linguistics para "Diglossia". Ambos casos son manejados.