Estoy tratando de crear un raspador usando Selenium y luego escribir datos en un archivo CSV. Cada vez que ejecuto el script a continuación, produce un data.csv pero la salida se reescribió en la misma fila una y otra vez, lo que resultó en una sola fila.

¿Cómo se escribe la salida en filas separadas?

import pandas as pd

elem = driver.find_elements_by_class_name("product-listing-row")
for ii in elem:
    pname = ii.find_element_by_class_name('product-name').text
    print('pname: ' + pname)
    psku = ii.find_element_by_class_name('product-code').text
    print('psku: ' + psku)
    thumb = ii.find_element_by_class_name('scaleAll').get_attribute('src')
    print('thumb: ' + thumb)
    link = ii.find_element_by_css_selector('a').get_attribute('href')
    print('address: ' + link)
    raw_data = {'Product_Name': [pname],
        'Product_SKU': [psku],
        'Product_ImageURL': [thumb],
        'Product _URL': [link]}
    df = pd.DataFrame(raw_data, columns = ['Product_Name', 'Product_SKU', 'Product_ImageURL', 'Product _URL'])
    df.to_csv (r'/Users/reezalaq/PycharmProjects/wholesale/data.csv')
0
Reezal 2040 6 oct. 2019 a las 17:26

4 respuestas

La mejor respuesta

El problema está aquí:

raw_data = {'Product_Name': [pname],
    'Product_SKU': [psku],
    'Product_ImageURL': [thumb],
    'Product _URL': [link]}

Por cada elem, sobrescribe raw_data. En cambio, puedes hacer algo así:

#initialize a list for your data
raw_data = []
for ii in elem:
    pname = ii.find_element_by_class_name('product-name').text
    print('pname: ' + pname)
    psku = ii.find_element_by_class_name('product-code').text
    print('psku: ' + psku)
    thumb = ii.find_element_by_class_name('scaleAll').get_attribute('src')
    print('thumb: ' + thumb)
    link = ii.find_element_by_css_selector('a').get_attribute('href')
    print('address: ' + link)
    raw_data_elem = {'Product_Name': pname,
        'Product_SKU': psku,
        'Product_ImageURL': thumb,
        'Product _URL': link}
    #add row to list
    raw_data.append(raw_data_elem)
df = pd.DataFrame(raw_data, columns = ['Product_Name', 'Product_SKU',   
        'Product_ImageURL', 'Product _URL'])
df.to_csv (r'/Users/reezalaq/PycharmProjects/wholesale/data.csv')
0
chefhose 7 oct. 2019 a las 12:07

Debe escribirlo en {{X0} } modo:

import pandas as pd

elem = driver.find_elements_by_class_name("product-listing-row")
header = True
for ii in elem:
    pname = ii.find_element_by_class_name('product-name').text
    psku = ii.find_element_by_class_name('product-code').text
    thumb = ii.find_element_by_class_name('scaleAll').get_attribute('src')
    link = ii.find_element_by_css_selector('a').get_attribute('href')
    raw_data = {'Product_Name': [pname],
        'Product_SKU': [psku],
        'Product_ImageURL': [thumb],
        'Product _URL': [link]}
    df = pd.DataFrame(raw_data, columns = ['Product_Name', 'Product_SKU', 'Product_ImageURL', 'Product _URL'])
    df.to_csv (r'/Users/reezalaq/PycharmProjects/wholesale/data.csv', mode="a", header=header)
    header = False

Esto agregará un encabezado a su csv solo en la primera iteración, luego agregará todas las filas nuevas al archivo.

Alternativamente, puede hacer el DataFrame una vez y luego guardarlo:

import pandas as pd

elem = driver.find_elements_by_class_name("product-listing-row")

raw_data = {'Product_Name': [],
        'Product_SKU': [],
        'Product_ImageURL': [],
        'Product_URL': []
}

for ii in elem:
    raw_data['Product_Name'].append(
        ii.find_element_by_class_name('product-name').text
    )
    raw_data['Product_SKU'].append(
        ii.find_element_by_class_name('product-code').text
    )
    raw_data['Product_ImageURL'].append(
        ii.find_element_by_class_name('scaleAll').get_attribute('src')
    )
    raw_data['Product_URL'].append(
        ii.find_element_by_css_selector('a').get_attribute('href')
    )

df = pd.DataFrame(raw_data)
df.to_csv (r'/Users/reezalaq/PycharmProjects/wholesale/data.csv')
0
Alex 6 oct. 2019 a las 14:37

Tienes que agregar cada elemento a la lista.

Esto es un ejemplo. Dentro del bucle, recupera el elemento y agrega el resultado a su lista que debe incluirse en el marco de datos fuera del bucle:

import pandas as pd

    raw_data = []
    for i in range(1,10):
        element = {'item': i }
        raw_data.append(element)

    df = pd.DataFrame(raw_data, columns = ['item'])
    df.to_csv ('./data.csv')
0
malcubierre 6 oct. 2019 a las 14:36

Cambiar a df.to_csv(r'/Users/reezalaq/PycharmProjects/wholesale/data.csv', mode='a', header=False)

0
PySeeker 6 oct. 2019 a las 14:32
58258204