Преобразование данных в DataFrame в Python

Dec 08 2020

С помощью @JaSON вот код, который позволяет мне получать данные в таблице из локального html, а код использует селен.

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)

Как эти строки преобразовать в действительную таблицу, которую я могу экспортировать в файл csv? Вот местная HTML-ссылкаhttps://pastebin.com/raw/hEq8K75C

** @Paul Brennan: После попытки отредактировать счетчик, чтобы быть, у counter-1меня есть 17 строк, чтобы временно пропустить ошибку строки 18, я получил filename.txt и вот снимок вывода

Ответы

1 PaulBrennan Dec 08 2020 at 19:56

Я изменил ваш код, чтобы сделать простой вывод. Это не очень питонично, так как не использует векторизованное создание Dataframe, но вот как это работает. Сначала настройте pandas, затем настройте фрейм данных (но мы еще не знаем столбцы), затем настройте столбцы на первом проходе (это вызовет проблемы, если есть переменные длины столбцов. Затем введите значения в фрейм данных

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

Как это можно улучшить, - это поместить элементы в строку в словарь и поместить их в фрейм данных. но я пишу это на своем телефоне, поэтому я не могу это проверить.

YasserKhalil Dec 11 2020 at 11:32

С большой помощью @Paul Brennan я мог изменить код, чтобы получить окончательный желаемый результат.

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

Код сейчас работает хорошо, но слишком медленно. Есть ли способ сделать это быстрее?