#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 и она такая же, как и на других страницах, поэтому я не понимаю, что там происходит. Должен ли я создать отдельную тему, чтобы спросить об этом?