Python: Obtener texto de html usando Beautifulsoup

Estoy tratando de extraer el número de texto de clasificación de este enlace . Ejemplo de enlace de usuario de Kaggle no1 . Más claro en una imagen:

introduzca la descripción de la imagen aquí

Estoy usando el siguiente código:

def get_single_item_data(item_url): sourceCode = requests.get(item_url) plainText = sourceCode.text soup = BeautifulSoup(plainText) for item_name in soup.findAll('h4',{'data-bind':"text: rankingText"}): print(item_name.string) item_url = 'https://www.kaggle.com/titericz' get_single_item_data(item_url) 

El resultado es None . El problema es que soup.findAll('h4',{'data-bind':"text: rankingText"}) produce:

[

]

pero en el html del enlace al inspeccionar esto es como:

1st

. Se puede ver en la imagen:

introduzca la descripción de la imagen aquí

Está claro que falta el texto. ¿Cómo puedo superar eso?

Edición: imprimiendo la variable de soup en el terminal puedo ver que este valor existe: introduzca la descripción de la imagen aquí

Así que debería haber una manera de acceder a través de la soup .

Edición 2: intenté sin éxito utilizar la respuesta más votada de esta pregunta de stackoverflow . Podría ser una solución por ahí.

Si no va a probar la automatización del navegador a través de selenium como sugirió @Ali, tendría que analizar el javascript que contiene la información deseada . Puedes hacerlo de diferentes maneras. Aquí hay un código de trabajo que ubica el script por un patrón de expresión regular , luego extrae el objeto de profile , lo carga con json en un diccionario de Python e imprime la clasificación deseada:

 import re import json from bs4 import BeautifulSoup import requests response = requests.get("https://www.kaggle.com/titericz") soup = BeautifulSoup(response.content, "html.parser") pattern = re.compile(r"profile: ({.*}),", re.MULTILINE | re.DOTALL) script = soup.find("script", text=pattern) profile_text = pattern.search(script.text).group(1) profile = json.loads(profile_text) print profile["ranking"], profile["rankingText"] 

Huellas dactilares:

 1 1st 

Los datos están en un enlace de datos usando javascript, como sugiere el atributo “enlace de datos”.

Sin embargo, si descarga la página con, por ejemplo, wget , verá que el valor de rankingText está realmente dentro de este elemento de script en la carga inicial:

 

Así que podrías usar eso en su lugar.

He resuelto su problema usando expresiones regulares en el texto plano:

 def get_single_item_data(item_url): sourceCode = requests.get(item_url) plainText = sourceCode.text #soup = BeautifulSoup(plainText, "html.parser") pattern = re.compile("ranking\": [0-9]+") name = pattern.search(plainText) ranking = name.group().split()[1] print(ranking) item_url = 'https://www.kaggle.com/titericz' get_single_item_data(item_url) 

Esto devuelve solo el número de rango, pero creo que te ayudará, ya que por lo que veo el texto de rango simplemente agrega ‘st’, ‘th’ y etc. a la derecha del número

Esto podría debido al llenado dynamic de datos.

Algunos códigos javascript, rellene esta etiqueta después de cargar la página. Por lo tanto, si obtiene el html utilizando solicitudes, aún no se ha completado.

 

Por favor, eche un vistazo al controlador web Selenium . Usando este controlador puede obtener la página completa y ejecutar js de manera normal.