Python – отличный выбор, когда дело доходит до автоматизации повторяющихся задач. В этой статье мы рассмотрим, как мы можем использовать силу Python для очистки веб -контента и преобразовать его в хорошо отформатированный документ Word.
Продолжить чтение, чтобы научиться:
- Содержит содержимого, используя
Beautifulsoup
- Преобразовать скрасные данные в формат слова с использованием
Пандок
Предположим, что у нас есть веб -сайт с каталогом книг, организованных в категории. Мы хотим иметь версию каталога в документе Word. По сути, два элемента этой проблемы: (1) Как мы собираем данные? и (2) как мы создаем документ Word из этих данных?
Примеры в этом уроке мы будем использовать следующий фиктивный веб -сайт, созданный для практики соскоба: http://books.toscrape.com/
Следующие шаги суммируют, что требуется для решения этой проблемы:
- Соберите данные со страницы индекса
- Соскребайте список ссылок на все страницы категории фильмов
- Посетите каждую страницу категории и соскребайте список фильмов в этой категории
- Посетите каждый фильм в каждой категории и соскажите соответствующие данные для этого фильма
- Формат собрал данные в строку разметки
- Хранить собранные данные как документ 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.
Шаги
- Соберите данные со страницы индекса
- Соскребайте список ссылок на все страницы категории фильмов
- Посетите каждую страницу категории и соскребайте список фильмов в этой категории
- Посетите каждый фильм в каждой категории и соскажите соответствующие данные для этого фильма
- Формат собрал данные в строку разметки
- Хранить собранные данные как документ 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”