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')
4 respuestas
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')
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')
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')
Cambiar a df.to_csv(r'/Users/reezalaq/PycharmProjects/wholesale/data.csv', mode='a', header=False)