Проект: Экспорт с Selenium

Материал из hpluswiki
Перейти к навигации Перейти к поиску

Черновик

Нужно дополнение SyntaxHighlight

Код не включает шаблоны, страницы участников и историю страниц в экспортируемые страницы и предназначен для демонстрации работы Selenium

На этой странице я, Experimentalist, поделюсь своими знаниями по Selenium для того, чтобы работать с веб-сайтами.

Selenium — это программно управляемый браузер, будь то Firefox или Chrome. Selenium состоит из двух главных частей: WebDriver, программа, управляющая браузером и библиотека для любимого вами языка. Я обычно загружаю WebDriver в свою пользовательскую директорию в Linux, "~/.local/bin" - директория, куда я могу складывать исполняемые файлы, она существует в переменной PATH как для Bash, так и для ZSH, этого мне достаточно. У вас может и не быть ZSH, поэтому правки "~/.bashrc" должно хватить.

Для примера мы рассмотрим этот сайт и экспорт страниц. В моём примере работает не всё, сколько бы я не говорил API "не задавать вопросов и сохранять файл", пользователю понадобится нажать одну кнопку. Диалога загрузки.

#!/usr/bin/env python3

"""
Transhumanist.online Mediawiki "all pages" downloader.
"""

from selenium import webdriver
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options
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 = []
    opts = Options()
    opts.headless = headless
    # Disable Selenium browser's cache
    profile = webdriver.FirefoxProfile()
    driver = webdriver.Firefox(profile, options=opts)
    # 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):
    opts = Options()
    opts.headless = headless
    # Disable Selenium browser's cache
    profile = webdriver.FirefoxProfile()
    # Set a save directory
    save_dir = getcwd()
    default_types = "application/xml, attachment/xml, text/xml"
    profile.set_preference("browser.download.dir", save_dir)
    profile.set_preference("browser.download.folderList", 2)
    profile.set_preference("browser.download.manager.showWhenStarting", False)
    profile.set_preference("browser.download.manager.useWindow", False)
    profile.set_preference("browser.download.manager.focusWhenStarting", False)
    profile.set_preference("browser.download.manager.showAlertOnComplete", False)
    profile.set_preference("browser.download.manager.closeWhenDone", True)
    profile.set_preference("browser.helperApps.alwaysAsk.force", False)
    profile.set_preference("browser.helperApps.neverAsk.saveToDisk", default_types)
    driver = webdriver.Firefox(profile, options=opts)
    # 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()