Converti i dati in DataFrame in Python

Dec 08 2020

Con l'aiuto di @JaSON, ecco un codice che mi consente di ottenere i dati nella tabella dall'html locale e il codice utilizza il selenio

from selenium import webdriver

driver = webdriver.Chrome("C:/chromedriver.exe")
driver.get('file:///C:/Users/Future/Desktop/local.html')
counter = len(driver.find_elements_by_id("Section3"))
xpath = "//div[@id='Section3']/following-sibling::div[count(preceding-sibling::div[@id='Section3'])={0} and count(following-sibling::div[@id='Section3'])={1}]"
print(counter)

for i in range(counter):
    print('\nRow #{} \n'.format(i + 1))
    _xpath = xpath.format(i + 1, counter - (i + 1))
    cells = driver.find_elements_by_xpath(_xpath)
    for cell in cells:
         value = cell.find_element_by_xpath(".//td").text
         print(value)

In che modo queste righe possono essere convertite in una tabella valida che posso esportare in un file CSV? Ecco il link HTML localehttps://pastebin.com/raw/hEq8K75C

** @Paul Brennan: Dopo aver provato a modificare il contatore per essere counter-1ho ricevuto 17 righe per saltare temporaneamente l'errore della riga 18, ho ottenuto il nome file.txt ed ecco l'istantanea dell'output

Risposte

1 PaulBrennan Dec 08 2020 at 19:56

Ho modificato il tuo codice per fare un semplice output. Questo non è molto pitonico in quanto non utilizza la creazione vettorializzata del Dataframe, ma ecco come funziona. Per prima cosa imposta i panda, poi imposta un dataframe (ma non conosciamo ancora le colonne) quindi imposta le colonne al primo passaggio (questo causerà problemi se ci sono lunghezze variabili delle colonne Quindi inserisci i valori nel dataframe

import pandas as pd
from selenium import webdriver

driver = webdriver.Chrome("C:/chromedriver.exe")
driver.get('file:///C:/Users/Future/Desktop/local.html')
counter = len(driver.find_elements_by_id("Section3"))
xpath = "//div[@id='Section3']/following-sibling::div[count(preceding-sibling::div[@id='Section3'])={0} and count(following-sibling::div[@id='Section3'])={1}]"
print(counter)

df = pd.Dataframe()

for i in range(counter):
    print('\nRow #{} \n'.format(i + 1))
    _xpath = xpath.format(i + 1, counter - (i + 1))
    cells = driver.find_elements_by_xpath(_xpath)
    if i == 0:
        df = pd.DataFrame(columns=cells) # fill the dataframe with the column names
    for cell in cells:
        value = cell.find_element_by_xpath(".//td").text
        #print(value)
        if not value:  # check the string is not empty
            # always puting the value in the first item
            df.at[i, 0] = value # put the value in the frame

df.to_csv('filename.txt') # output the dataframe to a file

Il modo in cui questo potrebbe essere migliorato è mettere gli elementi in una riga in un dizionario e inserirli nel datframe. ma sto scrivendo questo sul mio telefono quindi non posso provarlo.

YasserKhalil Dec 11 2020 at 11:32

Con il grande aiuto di @Paul Brennan, ho potuto modificare il codice in modo da ottenere l'output finale desiderato

import pandas as pd
from selenium import webdriver

driver = webdriver.Chrome("C:/chromedriver.exe")
driver.get('file:///C:/Users/Future/Desktop/local.html')
counter = len(driver.find_elements_by_id("Section3"))
xpath = "//div[@id='Section3']/following-sibling::div[count(preceding-sibling::div[@id='Section3'])={0} and count(following-sibling::div[@id='Section3'])={1}]"
finallist = []

for i in range(counter):
    #print('\nRow #{} \n'.format(i + 1))
    rowlist=[]
    _xpath = xpath.format(i + 1, counter - (i + 1))
    cells = driver.find_elements_by_xpath(_xpath)
    #if i == 0:
        #df = pd.DataFrame(columns=cells) # fill the dataframe with the column names
    for cell in cells:
        try:
            value = cell.find_element_by_xpath(".//td").text
            rowlist.append(value)
        except:
            break
    finallist.append(rowlist)
    
df = pd.DataFrame(finallist)
df[df.columns[[2, 0, 1, 7, 9, 8, 3, 5, 6, 4]]]

Il codice ora funziona bene ma è troppo lento. C'è un modo per renderlo più veloce?