В этой лабе вы напишите простое многопоточное приложение.

Scraper

Web scraping wiki - это процесс скачивания и последующего разбора веб страниц. Ваша задача - написать свой web-scraper, который полностью скачает все гиперссылки (<a href='ADDRESS'> элементы) в рамках этого сайта (во вне выходить нельзя, иначе мы скачаем весь интернет). То есть вам не надо качать картинки и страницы, а только сохранять сами адреса. По своей сути мы сделаем ограниченную версию wget. Примеры использования: тут и тут.

Экспериментировать можете с сайтом ru.wikipedia.org/wiki/Заглавная_страница.

Инструкции

Рекомендуется использовать библиотеку BeautifulSoup4. Русскоязычный туториал, официальная документация. Поставить пакет можно командой pip install beautifulsoup4.

Как должно всё работать

  1. Консольная утилита принимает как аргумент адрес сайта.
  2. Программа скачивает к себе в память html страницу по этому адресу.
  3. Программа разбирает html и ищет все <a> теги и извлекает href параметр.
  4. По каждому href идем в 1 пункт, так как внутри href хранится ссылка на страницу сайта.
  5. Когда-нибудь процесс остановится и результат - список уникальных страниц разделенных новой строкой, должен лежать одном файле.

Пример файла links.csv:

<https://en.wikipedia.org/wiki/Main_Page>
<https://en.wikipedia.org/wiki/Portal:Arts>
<https://en.wikipedia.org/wiki/Portal:Contents/Portals>
.... и так далее ....

Однопоточная версия

Напишите в лоб решение задачи. Можете сделать рекурсивно, можете обход в ширину или глубину. Как угодно. Ограничьте работу программы 1000-ей ссылок. Это понадобится нам для замера скорости работы.

Многопоточная версия с очередями

Есть несколько вариантов ускорить работу скрейпера. Можно использовать однопоточный, но асинхронный подход, а можно синхронный, но многопоточный. Мы попробуем второй способ.

Рассмотрим обычный подход для решения подобных задач - использование очереди задач и набора(pool) работников-потоков (thread workers).

Наша задача относится к классу задач, параллельних по данным. Нам нет смысла ждать, когда будет произведен разбор предыдущей ссылки, если у нас есть еще N штук таких же. Мы могли бы нашим работникам раздать задания - работник номер 1 возьми ссылки с 1 по 10, работник 2 - ссылки с 11 по 20 и так далее. Работники в процессе своей работы получат еще N других ссылок, которые они положат опять в некоторое хранилище ссылок на обработку.