Как использовать .append() с openpyxl для очистки содержимого нескольких веб-страниц

#python #web-scraping #openpyxl

#python #очистка веб-страниц #openpyxl

Вопрос:

Я пытаюсь создать код для очистки сценария «Братства кольца» с веб-сайта и вставить его в электронную таблицу Excel. Я начал с создания кода для выполнения этого для одной страницы, и все было в порядке, однако, когда я добавил цикл для просмотра всех страниц, содержащих скрипт, я столкнулся с проблемой, из-за которой содержимое электронной таблицы перезаписывается каждый раз, когда очищается новая страница.

Просматривая документацию для openpyxl , я понимаю, что мне следует использовать .append() , и я попытался сделать это внутри if цикла после создания переменной fname = 'script.xlsx' (не показана в этом коде). Само собой разумеется, что это не сработало, в итоге у меня получилась электронная таблица, содержащая только содержимое первой ячейки первой страницы.

Я также прочитал некоторые старые темы, в которых предлагается указать ячейку с .cell() , куда вставить текст, однако я не уверен, что это было бы лучшим решением, поскольку количество строк таблиц отличается для каждой веб-страницы.

Не мог бы кто-нибудь указать мне правильное направление?

 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()
  

Ответ №1:

Две вещи:

  • Строка на листе Excel не соответствует строке на веб-странице. Строка Excel должна быть установлена отдельно.
  • Открытие и сохранение листа в каждой строке значительно замедляет процесс. В случае возникновения проблемы должно быть достаточно одного открытия для каждой веб-страницы.

Вот обновленный код:

 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()
  

Комментарии:

1. Спасибо, ваше решение — это то, что мне было нужно. Теперь я заметил другую проблему, начиная со «сцены 25», она перестает записывать содержимое второго столбца, я проверил структуру xpath и она такая же, как и на других страницах, поэтому я не понимаю, что там происходит. Должен ли я создать отдельную тему, чтобы спросить об этом?