Рубрики
Без рубрики

От Интернета к слову, используя Python

Python – отличный выбор, когда дело доходит до автоматизации повторяющихся задач. В этой статье мы будем L … с меткой Python, BeautifulSoup, Pandoc.

Python – отличный выбор, когда дело доходит до автоматизации повторяющихся задач. В этой статье мы рассмотрим, как мы можем использовать силу Python для очистки веб -контента и преобразовать его в хорошо отформатированный документ Word.

Продолжить чтение, чтобы научиться:

  • Содержит содержимого, используя Beautifulsoup
  • Преобразовать скрасные данные в формат слова с использованием Пандок

Предположим, что у нас есть веб -сайт с каталогом книг, организованных в категории. Мы хотим иметь версию каталога в документе Word. По сути, два элемента этой проблемы: (1) Как мы собираем данные? и (2) как мы создаем документ Word из этих данных?

Примеры в этом уроке мы будем использовать следующий фиктивный веб -сайт, созданный для практики соскоба: http://books.toscrape.com/

Следующие шаги суммируют, что требуется для решения этой проблемы:

  1. Соберите данные со страницы индекса
  2. Соскребайте список ссылок на все страницы категории фильмов
  3. Посетите каждую страницу категории и соскребайте список фильмов в этой категории
  4. Посетите каждый фильм в каждой категории и соскажите соответствующие данные для этого фильма
  5. Формат собрал данные в строку разметки
  6. Хранить собранные данные как документ Word

Первый шаг – получить данные со страницы индекса:

from urllib.request import urlopen
from bs4 import BeautifulSoup


def collect_website_data(url):
    """
    Takes url string parameter, returns BeautifulSoup object with website content
    """
    index_page = urlopen(url) # HTTP Response
    scrape_data = BeautifulSoup(index_page, "html.parser") # BeatifulSoup Object
    return scrape_data


if __name__ == "__main__":
    BASE_URL = "http://books.toscrape.com/"
    page_data = collect_website_data(BASE_URL)

Давайте поймем, что происходит в сценарии выше. Мы определяем функцию, называемую collect_website_data Анкет Эта функция принимает строку в качестве параметра. Мы ожидаем, что это будет URL -адрес страницы, которую мы хотим очистить.

Здесь мы используем Урлопен Метод из urllib.request библиотека.

Ответ HTTP затем преобразуется в BeautifulSoup Объект, и теперь он готов к соскоб.

В Главный Раздел сценария, мы называем collect_website_data функционируйте и предоставьте Base_url как параметр.

Теперь, когда у нас есть объект для сети для работы, нам нужно выяснить, как получить список всех страниц категорий.

Для этой цели мы создаем другую функцию

...

def get_list_of_category_urls(bs_object, base_url):
    """
    Takes a BeautifulSoup object as parameter, returns a list of urls
    """
    category_a_elements = bs_object.find("div", {"class": "side_categories"}).li.ul.findAll("a")
    category_links = []

    for item in category_a_elements:
        href = base_url + item.get("href")
        category_links.append(href)

    return category_links


if __name__ == "__main__":
    ...
    links_to_categories = get_list_of_category_urls(page_data, BASE_URL)

get_list_of_category_urls принимает два параметра: объект BeautifulSoup и строка, представляющая базовый URL.

Анализ секции боковой панели категории показывает, что

держит меню боковой панели.

Тем не менее, нам нужно свернуть ребенку

    элемент и найдите все Элементы там. Используя BeautifulSoup, это может быть достигнуто так:

    category_a_elements = bs_object.find("div", {"class": "side_categories"}).li.ul.findAll("a")
    

    Поскольку это не прекрасный учебник как сам. Я передаю вас в Красивая документация Для получения дополнительной информации и примеров.

    Далее мы тогда используем для петля, чтобы пройти каждый элемент в списке, чтобы выбрать href имущество. Потому что все hrefs Относительны в нашем примере, нам нужно префикс Base_url каждому для составления списка абсолютных ссылок.

    for item in category_a_elements:
            href = base_url + item.get("href")
            category_links.append(href)
    

    С каждой петлей, а href Предмет добавлен в Category_links = [] список. После езды на велосипеде через все категории мы возвращаем список строк, которые являются полными URL -адресами на страницы категорий.

    Мы храним список в Links_to_categories переменная.

    Со списком URL -адресов категории готовы, мы теперь можем приступить к тому, чтобы написать скрипт скрепования, который посетит каждую страницу и получает нужную информацию, которую мы хотим.

    Давайте начнем с чего -то простого, например, получение заголовка категории с каждой страницы категории:

    ...
    
    def get_category_titles_from_each_page(list_of_urls):
        """
        Takes a list of urls, returns category titles from each visited page
        """
        titles = []
    
        for url in list_of_urls:
            category_page = urlopen(url)
            scrape_data = BeautifulSoup(
                category_page, "html.parser")  # BeatifulSoup Object
            title = scrape_data.h1.text
            titles.append(title)
    
        return(titles)
    
    
    if __name__ == "__main__":
        ...
        titles = get_category_titles_from_each_page(links_to_categories)
    
    

    Используя список, который мы имеем в Links_to_categories В качестве ввода мы запускаем get_category_titles_from_each_page функция

    Функция использует пустой список с именем названия . Затем мы используем для Цикл, чтобы повторить процесс запроса веб -страницы и преобразования ее в объект BeautifulSoup, а затем получить текст

    тег из этого. С каждым запуска мы добавляем названия список. Заполненный список – это то, что возвращает функция.

    Следующим шагом является преобразование списка записей в строку разметки.

    Зачем Маркдаун? Это позволяет нам применять простые методы манипулирования строками на необработанном тексте, чтобы превратить его в Markdown. Формат разметки может быть легко преобразован в ряд выходных форматов.

    Для целей этого упражнения нам нужно знать следующие принципы отметки:

    # One '#' marks a h1 header
    
    ## Two '#'s mark a h2 header
    
    This will be a paragraph
    
    This will another paragraph
    

    Apply_markdown_formatting Функция префиксов a # За последующим пространство и суффиксы с двумя новыми линиями \ n \ n персонажи.

    ...
    
    def apply_markdown_formatting(list_of_records):
        """
        Takes an iterable, returns markdown formatted string
        """
        markdown_string = ""
    
        for item in list_of_records:
            line = "#" + " " + item + "\n\n"
            markdown_string += line
    
        return markdown_string
    
    
    if __name__ == "__main__":
        ...
        markdown = apply_markdown_formatting(titles)
    
    

    Если мы запустим print (markdown_string) Мы должны получить что -то вроде этого:

    # Travel
    
    # Mystery
    
    # Historical Fiction
    
    # Sequential Art
    ...
    

    Пришло время проверить, сможем ли мы успешно преобразовать строку Markdown в документ Word.

    Для этого вам нужно будет Установите Universal Document Converter Pandoc Анкет Pandoc доступен в Windows, MacOS, а также Linux. Pandoc поддерживает большое количество форматов разметки документов и не ограничивается разметкой и словом.

    В самом скрипте мы будем использовать pypandoc Библиотека, которая обеспечивает тонкую обертку для Pandoc. Вы также можете установить дополнительный фильтр под названием Pandoc-Docx-Pagebreakpy что позволит вам вставить разрывы страницы в вывод слова. Оба пакета доступны на PYPI и могут быть установлены через PIP.

    ...
    import pypandoc
    ...
    
    def convert_markdown_to_docx(markdown_string):
        """
        Takes a markdown string, converts it to docx
        """
        filters = ['pandoc-docx-pagebreakpy']
        output = pypandoc.convert_text(
            markdown_string, 'docx', format='md', outputfile="output.docx", filters=filters)
        pass
    
    
    if __name__ == "__main__":
        ...
        convert_markdown_to_docx(markdown)
    

    Вуаля! Мы создали документ Word из скребки данных! output.docx Файл должен содержать список категорий скрещенных фильмов, отформатированных как Заголовок 1 Анкет

    Это обеспечивает функциональность с голой кости для сценария с веб-сайтом, но давайте немного его оживим.

    Рассмотрим следующую функцию get_info_for_each_film который объединяет функциональность get_category_titles_from_each_page и Apply_markdown_formatting Анкет Мы будем повторно использовать collect_website_data и get_list_of_category_urls а также convert_markdown_to_docx функции:

    import progressbar
    import pypandoc
    from urllib.request import urlopen
    from bs4 import BeautifulSoup
    
    
    def collect_website_data(url):
        ...
        return scrape_data
    
    
    def get_list_of_category_urls(bs_object, base_url):
        ...
        return category_links
    
    
    def get_info_for_each_film(list_of_urls, base_url):
        """
        Takes a list of urls, returns markdown formatted string
        """
        markdown_string = ""
    
        print('Retrieving film data for each category:')
        with progressbar.ProgressBar(max_value=len(list_of_urls)) as bar:
            for counter, url in enumerate(list_of_urls):
                category_page = urlopen(url)
                scrape_data = BeautifulSoup(
                    category_page, "html.parser")
                category = scrape_data.h1.text
                category_md = "#" + " " + category + "\n\n"
                markdown_string += category_md
                links_to_films = scrape_data.find_all("h3")
                links_to_films = [base_url + "catalogue/" +
                                  i.a.get("href")[9:] for i in links_to_films]
                for film_link in links_to_films:
                    film_page = urlopen(film_link)
                    scrape_data = BeautifulSoup(
                        film_page, "html.parser")
                    film_title = scrape_data.h1.text
                    film_title_md = "##" + " " + film_title + "\n"
                    markdown_string += film_title_md
                    try:
                        description = scrape_data.find(
                            "div", {"id": "product_description"}).next_sibling.next_sibling.text
                        description_md = description + "\n\n"
                        markdown_string += description_md
                    except AttributeError as e:
                        markdown_string += '\n\n'
                markdown_string += '\\newpage'
                bar.update(counter)
        return markdown_string
    
    
    def convert_markdown_to_docx(markdown_string):
        ...
        pass
    
    
    if __name__ == "__main__":
        BASE_URL = "http://books.toscrape.com/"
        page_data = collect_website_data(BASE_URL)
        links_to_categories = get_list_of_category_urls(page_data, BASE_URL)
        film_data = get_info_for_each_film(links_to_categories, BASE_URL)
        convert_markdown_to_docx(film_data)
    
    

    Приведенная выше функция будет выполнять необходимую сеть и форматирование строк для создания допустимой строки разметки за один раз.

    Поскольку скрипт занимает некоторое время, я также добавил ProgressBar, используя ProgressBar2 библиотека. В панели прогресса используется длину списка, содержащих URL -адреса категории, для установки максимального диапазона для увеличения прогресса. перечислять Метод добавляет счетчик к для Цикл, который мы можем использовать, чтобы увеличить прогресс стержня.

    Чтобы сценарий был более полезным, мы можем просверлить и соскрести данные из каждой пленки в каждой категории. Целью будет создание документа, который будет следовать этой шаблоне:

    [Heading 1] -- Category
        [Heading 2] -- Title
            [Paragraph] -- Film description
    

    Каждая категория станет Заголовок 1 С каждым названием фильма становится Заголовок 2 Анкет Мы также добавим Абзац с описанием соскребного фильма.

    Для этого нам нужно перечислить URL -адреса для фильмов на каждой странице категории. Анализ базового HTML показывает, что ссылки на фильмы содержатся в H3 Элементы на страницах категории. Первый шаг – тогда получить все H3 элементы. Чтобы получить URL -адреса для страниц фильма, я использую понимание списка, которое, возможно, жертвует часть читаемости кода для краткости:

    links_to_films = scrape_data.find_all("h3")
    links_to_films = [base_url + "catalogue/" + i.a.get("href")[9:] for i in links_to_films]
    

    Давайте рассмотрим, что здесь происходит: для каждого элемента в Links_to_films , получить href Собственность из A Теги, отделка символов с начала строки (те, которые относятся к относительным URL -символам в ссылке), приготовление base_url переменная, а также «каталог/». Вместе это создает список URL -адресов страниц фильма, то есть:

    [
    ...
    "http://books.toscrape.com/catalogue/emma_17/index.html",
    "http://books.toscrape.com/catalogue/alice-in-wonderland-alices-adventures-in-wonderland-1_5/index.html"
    ...
    ]
    

    Вложенный для Loop позволяет нам сверлить до каждой страницы пленки и соскрести данные из него. Некоторые из красивых хитростей, таких как удвоенные Next_sibling В этом примере объясняется в BeautifulSoup Documentation :

    description = scrape_data.find(
                            "div", {"id": "product_description"}).next_sibling.next_sibling.text
    

    Короче говоря, один Next_sibling Понимает только белое пространство между элементами. Второй Next_sibling правильно извлекает P Элемент, который содержит описание фильма.

    Я добавил Попробуйте/кроме блокировать вокруг Описание Скребок, чтобы справиться с ситуациями, где фильмы не имеют описаний.

    При использовании Pandoc для экспорта в документ Word, \\ newpage Тег потребует, чтобы вы установили Pandoc-Docx-Pagebreakpy Анкет

    Вы можете проверить полный сценарий на GitHub:

    Pavstermeister/web-to-doc

    Скрипт Python, который очищает контент с веб -страницы, преобразует его в строку разметки и выводит документ Word.

    Использование Python 3.6.12.

    Шаги

    1. Соберите данные со страницы индекса
    2. Соскребайте список ссылок на все страницы категории фильмов
    3. Посетите каждую страницу категории и соскребайте список фильмов в этой категории
    4. Посетите каждый фильм в каждой категории и соскажите соответствующие данные для этого фильма
    5. Формат собрал данные в строку разметки
    6. Хранить собранные данные как документ Word

    Проверьте связанную статью на dev.to – https://dev.to/pavstermeister/from-web-to-word-using-python-4gd9

    Внешние зависимости

    Используются внешние библиотеки Python

    Вдохновение для написания этой статьи произошло из -за проблемы, которую я должен был решить в последнее время. На своей повседневной работе я являюсь ИТ -аналитиком в большом университете. Один из административных офисов попросил помощи, чтобы обеспечить улучшенный способ создания документа Word, содержащего экспорт данных о курсах аспирантуры, доступных на веб -сайте курсов.

    Процесс создания файла будет включать сотрудника, проходящего около 200 страниц курса, тщательно копируя и вставьте информацию об курсе в файл Word. Этот файл слов послужит источником для печатной версии проспекта аспиранта колледжа.

    После некоторой пробной и ошибки методология, изложенная выше, работала выше, и в итоге я получил документ Word, структурированный более или менее похож на это:

    [Heading 1] -- Faculty
        [Heading 2] -- School
            [Heading 3] -- Course title
                [Paragraph] -- Course details
                [Paragraph] -- Course description
                [Paragraph] -- Course requirements
    

    Окончательные выходные файлы были хорошо приняты в рассматриваемый офис, и я получил несколько хороших отзывов 😄:

    Как однажды выразил Кларк: «Любая достаточно продвинутая технология неотличима от магии». И это магия, она будет иметь огромную помощь для развития проспекта.

    Приятно видеть, как немного программирования может сделать чью -то жизнь намного проще.

    Прежде чем ты уйдешь… Если вам понравилась эта статья, нажмите кнопку «Следующие». Рассмотреть возможность Следуйте за мной в Твиттере . До скорого:)

    Оригинал: “https://dev.to/pavstermeister/from-web-to-word-using-python-4gd9”