Проект: Экспорт с Selenium
Черновик
Код не включает шаблоны, страницы участников и историю страниц в экспортируемые страницы и предназначен для демонстрации работы Selenium
На этой странице я, Experimentalist, поделюсь своими знаниями по Selenium для того, чтобы работать с веб-сайтами.
Selenium — это программно управляемый браузер, будь то Firefox или Chrome. Selenium состоит из двух главных частей: WebDriver, программа, управляющая браузером и библиотека для любимого вами языка. Я обычно загружаю WebDriver в свою пользовательскую директорию в Linux, "~/.local/bin" - директория, куда я могу складывать исполняемые файлы, она существует в переменной PATH как для Bash, так и для ZSH, этого мне достаточно. У вас может и не быть ZSH, поэтому правки "~/.bashrc" должно хватить.
Для примера мы рассмотрим этот сайт и экспорт страниц. Использовать я буду Google Chromium и chromium-chromedriver из Ubuntu Linux, как очень распространённые штуки, которые может установить почти каждый. В будущем этот пример стоит переделать, выводя опции наружу функций, запускающих Chromium, или вообще используя один процесс браузера, но пока и так сойдёт. Также мы предполагаем, что загрузка занимает менее 60 секунд.
#!/usr/bin/env python3
"""
Transhumanist.online Mediawiki "all pages" downloader.
"""
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from os import getcwd
import time
ALL_PAGES_URL = "https://transhumanist.online/Служебная:Все_страницы"
EXPORT_URL = "https://transhumanist.online/Служебная:Экспорт"
ALL_PAGES_ITEM_QUERY = ".mw-allpages-body > ul.mw-allpages-chunk > li"
EXPORT_TEXTAREA_QUERY = "textarea.oo-ui-inputWidget-input"
EXPORT_TODO_ENABLE_TEMPLATES_QUERY = ""
EXPORT_BUTTON_QUERY = "div.mw-htmlform-submit-buttons button[type=\"submit\"]"
def obtain_page_list(headless=True):
result = []
chrome_options = webdriver.ChromeOptions()
# Configure headless Chrome options
chrome_options.add_argument("--headless")
# Wonder if it is needed at all for a headless downloader
chrome_options.add_argument("--window-size=1920x1080")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--verbose')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-software-rasterizer')
# Create a Chromedriver instance
driver = webdriver.Chrome(chrome_options=chrome_options)
# Launch browser with our url
driver.get(ALL_PAGES_URL)
# Extract a page list
try:
page_items = driver.find_elements_by_css_selector(ALL_PAGES_ITEM_QUERY)
page_items = [page_item.get_attribute("textContent") for page_item in page_items]
result = page_items
except NoSuchElementException as e:
print("No such element", e)
driver.quit()
return(result)
def download_exported_pages(page_names, headless=True):
chrome_options = webdriver.ChromeOptions()
# Configure headless Chrome options
chrome_options.add_argument("--headless")
# Wonder if it is needed at all for a headless downloader
chrome_options.add_argument("--window-size=1920x1080")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--verbose')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-software-rasterizer')
# Set a save directory
save_dir = getcwd()
# default_types = "application/xml, attachment/xml, text/xml"
chrome_options.add_experimental_option("prefs", {
"download.default_directory": save_dir,
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing_for_trusted_sources_enabled": False,
"safebrowsing.enabled": False
})
# Create a Chromedriver instance
driver = webdriver.Chrome(chrome_options=chrome_options)
# Log a save directory
print('Saving a file to "{}"...'.format(save_dir))
# Launch browser with our url
driver.get(EXPORT_URL)
# Wait for a close button to be there.
# Otherwise, the page is not ready
try:
# https://selenium-python.readthedocs.io/waits.html
WebDriverWait(driver, 60).until(
expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, EXPORT_BUTTON_QUERY))
)
except TimeoutException:
print("Loading took too much time!")
# Enter a page list to a textarea
try:
export_textarea = driver.find_element_by_css_selector(EXPORT_TEXTAREA_QUERY)
export_textarea.clear()
export_textarea.send_keys('\n'.join(page_names))
except NoSuchElementException as e:
print("Markup changed, a CSS selector for EXPORT_TEXTAREA_QUERY needs an update", e)
driver.quit()
return
# Press an export button to export elements
try:
export_button = driver.find_element_by_css_selector(EXPORT_BUTTON_QUERY)
export_button.click()
except NoSuchElementException as e:
print("Markup changed, a CSS selector for EXPORT_BUTTON_QUERY needs an update")
driver.quit()
return
# Sleep and exit
print("Exiting in 60...")
time.sleep(60)
# Close the browser
driver.quit()
def main():
"""Main function"""
page_items = obtain_page_list()
download_exported_pages(page_items, headless=False)
if __name__ == '__main__':
main()