impossible d'analyser le tableau html avec Beautiful Soup

Oct 05 2020

Je suis très novice dans l'utilisation de Beautiful Soup et j'essaie d'importer des données à partir de l'URL ci-dessous en tant que dataframe pandas. Cependant, le résultat final a les noms de colonnes corrects, mais aucun numéro pour les lignes. Que dois-je faire à la place?

Voici mon code:

from bs4 import BeautifulSoup
import requests

def get_tables(html):
    soup = BeautifulSoup(html, 'html.parser')
    table = soup.find_all('table')
    return pd.read_html(str(table))[0]

url = 'https://www.cmegroup.com/trading/interest-rates/stir/eurodollar.html'
html = requests.get(url).content
get_tables(html)

Réponses

3 AndrejKesely Oct 05 2020 at 02:15

Les données que vous voyez dans le tableau sont chargées à partir d'une autre URL via JavaScript. Vous pouvez utiliser cet exemple pour enregistrer les données dans csv:

import json
import requests 
import pandas as pd

data = requests.get('https://www.cmegroup.com/CmeWS/mvc/Quotes/Future/1/G').json()

# uncomment this to print all data:
# print(json.dumps(data, indent=4))

df = pd.json_normalize(data['quotes'])
df.to_csv('data.csv')

Sauvegarde data.csv(capture d'écran de LibreOffice):

1 ChrisGreening Oct 05 2020 at 02:25

Le site Web à partir duquel vous essayez de récupérer les données affiche les valeurs de la table de manière dynamique et l'utilisation requests.getne renvoie que le code HTML envoyé par le serveur avant le rendu JavaScript. Vous devrez trouver un autre moyen d'accéder aux données ou de rendre les pages Web JS ( voir cet exemple ).

Une façon courante de faire cela consiste à utiliser le sélénium pour automatiser un navigateur qui vous permet de rendre le JavaScript et d'obtenir le code source de cette façon.

Voici un exemple rapide:

import time 

import pandas as pd 
from selenium.webdriver import Chrome

#Request the dynamically loaded page source 
c = Chrome(r'/path/to/webdriver.exe')
c.get('https://www.cmegroup.com/trading/interest-rates/stir/eurodollar.html')

#Wait for it to render in browser
time.sleep(5)
html_data = c.page_source

#Load into pd.DataFrame 
tables = pd.read_html(html_data)
df = tables[0]
df.columns = df.columns.droplevel()    #Convert the MultiIndex to an Index 

Notez que je n'ai pas utilisé BeautifulSoup, vous pouvez passer directement le html à pd.read_html. Vous devrez faire un peu plus de nettoyage à partir de là, mais c'est l'essentiel.

Alternativement, vous pouvez prendre un pic à requests-html qui est une bibliothèque qui offre un rendu JavaScript et pourrait être en mesure de vous aider, de rechercher un moyen d'accéder aux données en tant que JSON ou .csv depuis ailleurs et de l'utiliser, etc.