Konwertuj dane na DataFrame w Pythonie

Dec 08 2020

Z pomocą @JaSON, oto kod, który pozwala mi uzyskać dane w tabeli z lokalnego html, a kod używa selenu

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)

W jaki sposób te wiersze można przekonwertować na prawidłową tabelę, którą mogę wyeksportować do pliku csv? Oto lokalny link HTMLhttps://pastebin.com/raw/hEq8K75C

** @Paul Brennan: Po próbie edycji licznika na counter-1mam 17 wierszy, aby tymczasowo pominąć błąd w wierszu 18, otrzymałem nazwę pliku.txt i oto migawka wyniku

Odpowiedzi

1 PaulBrennan Dec 08 2020 at 19:56

Zmodyfikowałem Twój kod, aby wykonać proste wyjście. Nie jest to zbyt Pythonowe, ponieważ nie wykorzystuje wektoryzowanego tworzenia Dataframe, ale oto jak to działa. Najpierw skonfiguruj pandy, następnie ustaw ramkę danych (ale nie znamy jeszcze kolumn), a następnie ustaw kolumny w pierwszym przebiegu (spowoduje to problemy jeśli są kolumny o zmiennej długości Następnie wprowadź wartości do ramki danych

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

Jak można to poprawić, należy umieścić pozycje w rzędzie w słowniku i umieścić je w ramce danych. ale piszę to na swoim telefonie, więc nie mogę tego przetestować.

YasserKhalil Dec 11 2020 at 11:32

Z wielką pomocą @Paul Brennan mogłem zmodyfikować kod tak, aby uzyskać ostateczny pożądany wynik

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]]]

Kod działa teraz dobrze, ale jest za wolny. Czy jest sposób, aby to przyspieszyć?