Estoy tratando de crear un código para raspar el guión de "La comunidad del anillo" de un sitio web y pegarlo en una hoja de cálculo de Excel. Comencé creando el código para hacer esto para una página y todo estaba bien, sin embargo, cuando agregué un bucle para recorrer todas las páginas que contienen el script, encontré un problema en el que el contenido de la hoja de cálculo se sobrescribe cada vez se raspa una nueva página.

Mirando la documentación de openpyxl, entiendo que debería usar .append(), e intenté hacerlo, dentro del ciclo if después de crear la variable fname = 'script.xlsx' ( no se muestra en este código). No hace falta decir que no funcionó, terminé teniendo una hoja de cálculo con solo el contenido de la primera celda de la primera página.

También leí algunos hilos antiguos que sugieren especificar la celda con .cell() donde pegar el texto, sin embargo, no estoy seguro de que sea la mejor solución, ya que el número de filas de las tablas es diferente para cada web. página.

¿Podría alguien señalarme en la dirección correcta?

from selenium import webdriver
import os
import openpyxl
from openpyxl import Workbook

driver = webdriver.Chrome()
# divides url into 3 parts to loop through the pages
url1 = 'http://www.ageofthering.com/atthemovies/scripts/fellowshipofthering'
url2 = 'to'
url3 = '.php'
# main loop: browses the various pages of the script
# f: first number in page url
for f in range(1, 38, 4):
    # s: second number in page url
    s = f + 3
    # combines the url
    url = url1 + str(f) + url2 + str(s) + url3
    driver.get(url)
    # finds length of row and column tags on webpage
    rows = len(driver.find_elements_by_xpath("//*[@id='AutoNumber1']/tbody/tr"))
    columns = len(driver.find_elements_by_xpath("//*[@id='AutoNumber1']/tbody/tr[3]/td"))
    # divides url into 3 parts to loop through the rows and columns
    first = "//*[@id='AutoNumber1']/tbody/tr["
    second = "]/td["
    third = "]"
    # loops through the rows (r) and columns (c) of each page
    # try/except are used to consider rows with only 1 column
    for r in range(1, rows+1):
        for c in range(1, columns+1):
            try:
                # combines the xpath of each cell of the table
                final = first + str(r) + second + str(c) + third
                # stores the content of each cell in a variable (data)
                data = driver.find_element_by_xpath(final).text
                # writes content of table in an Excel spreadsheet
                fname = 'script.xlsx'
                if os.path.exists(fname):
                    workbook = openpyxl.load_workbook(fname)
                    worksheet = workbook.get_sheet_by_name('Sheet')
                else:
                    workbook = Workbook()
                    worksheet = workbook.active
                worksheet.cell(row=r, column=c).value = data
                workbook.save(fname)
            except:
                continue
# closes Chrome
driver.quit()
0
Lorenzo 27 ago. 2020 a las 00:19

1 respuesta

La mejor respuesta

Dos cosas:

  • La fila de la hoja de Excel no coincide con la fila de la página web. La fila de Excel debe establecerse por separado.
  • Abrir y guardar la hoja en cada fila ralentiza considerablemente el proceso. Abrir una vez por página web debería ser suficiente en caso de que surja un problema.

Aquí está el código actualizado:

from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
import os
import openpyxl
from openpyxl import Workbook

options = webdriver.ChromeOptions()
options.add_argument("disable-extensions")
options.add_argument("disable-plugins")
options.experimental_options["useAutomationExtension"] = False  # prevent load error - Error Loading Extension - Failed to load extension from ... - Could not load extension from ... Loading of unpacked extensions is disabled
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)

# divides url into 3 parts to loop through the pages
url1 = 'http://www.ageofthering.com/atthemovies/scripts/fellowshipofthering'
url2 = 'to'
url3 = '.php'
# main loop: browses the various pages of the script
# f: first number in page url
rpaste = 1  # paste data in excel
for f in range(1, 38, 4):
    # s: second number in page url
    s = f + 3
    # combines the url
    url = url1 + str(f) + url2 + str(s) + url3
    driver.get(url)
    # finds length of row and column tags on webpage
    rows = len(driver.find_elements_by_xpath("//*[@id='AutoNumber1']/tbody/tr"))
    columns = len(driver.find_elements_by_xpath("//*[@id='AutoNumber1']/tbody/tr[3]/td"))
    # divides url into 3 parts to loop through the rows and columns
    first = "//*[@id='AutoNumber1']/tbody/tr["
    second = "]/td["
    third = "]"
    fname = 'script.xlsx'
    if os.path.exists(fname):
        workbook = openpyxl.load_workbook(fname)
        worksheet = workbook['Sheet']
    else:
        workbook = Workbook()
        worksheet = workbook.active
    # loops through the rows (r) and columns (c) of each page
    # try/except are used to consider rows with only 1 column
    print('Paste Row', rpaste)
    for r in range(1, rows+1):
        while worksheet.cell(rpaste, 1).value:   # get next empty row in sheet
            rpaste += 1
        for c in range(1, columns+1):
            try:
                # combines the xpath of each cell of the table
                final = first + str(r) + second + str(c) + third
                # stores the content of each cell in a variable (data)
                data = driver.find_element_by_xpath(final).text
                if c == 1 and "Scene" in data and "~" in data: # add extra empty row if new scene
                    rpaste += 1
                # writes content of table in an Excel spreadsheet
                worksheet.cell(rpaste, column=c).value = data
            except:
                continue
    workbook.save(fname)
# closes Chrome
driver.quit()
0
Mike67 26 ago. 2020 a las 23:02