Transcription
Всем привет. Рада вас видеть. Напишите, пожалуйста, в чат плюс, если меня видно и слышно.
Так, давайте пару минут подождём и начнём наш открытый урок, на котором мы обсудим, как собирать сайты своими руками. Плюсики вижу. Это приятно. Рада вас видеть. Да, Александр, у нас сейчас открыт урок про парсинг сайтов. Просто кто-то уже был на прямом предыдущем открытом уроке, который был 2 часа назад по рекомендательным системам. А сейчас мы будем говорить про парсинг сайтов. Всё так. А именно у нас на повестке дня основы парсинга сайта, про который мы сейчас и начнём говорить. И сейчас я расшарю экран. И, а сейчас его должно быть видно. Я не буду убирать плашку, потому что на предыдущем уроке, когда я убрала плашку, у меня начало катастрофически отваливаться демонстрация экрана. Вот, чтобы следить, идёт демонстрация экрана или нет, пусть у нас будет небольшая плашечка. Звук, связь мы с вами проверили.
И давайте немножко с вами познакомимся. Очень интересно узнать, кто сегодня здесь со мной собрался. А напишите, пожалуйста, из какого вы города. Если вы уже писали на предыдущем уроке по рекомендательным системам, можете этот пункт пропустить. Вот. Если у вас опыт работы в IT, с какой целью вы пришли сегодня? А если честно, своим приходом вы меня очень вдохновляете. Потому что в такой потрясающий почти летний вечер видеть таких заражённых людей здесь с нами в Life Digital, это очень-очень приятно. Спасибо, что пришли. Рады, что тема парсинга сайтов актуальна и интересует вас.
В ответ, а тоже познакомлюсь и пару слов скажу про себя. Меня зовут Мария Тихонова. Я ваш покорный слуга. А я кандидат компьютерных наук и руковожу исследовательским кластером в Сбере. По сути, развиваю науку у нас в Сбере. А и, а помимо этого, я доцент Высшей школы экономики, как раз-таки преподаю дисциплины, связанные с LLM, с NLP и машинным обучением. Про всё это я, кстати, рассказываю в Telegram-канале. А, и там же я обязательно скину все материалы, включая запись и практику. А мне кажется, практика сегодня самое интересное по открытому уроку. Так что, а всё будет там. А сейчас в ответ переключусь обратно на демонстрацию, посмотрю, что вы пишете, а заодно скину ник своего Telegram-канала, если вдруг, а кому-то актуально. А будем парсить books to scrape. Григорий, вот у нас сегодня, а, собственно, занятие по парсингу. Так, всё, Григорий уже про себя написал. Вот. А мы будем использовать сегодня библиотеку Requests, Beautiful Soup. Классические инструменты, но они самые стабильные, простые, я их люблю. Например, мы с коллегами сейчас делаем парсилку конференций, чтобы скачивать себе PDF-ки статей из самых разных конференций. Как раз-таки Requests — просто наше всё, потому что самый такой надёжный, стабильный инструмент, как два пальца об асфальт. Простите за аналогию.
Что ж, давайте, давайте продолжим. Кто ещё дописывает, дописывайте, а я пару слов скажу про правила вебинара, которые позволят наши занятия сделать максимально комфортным сегодня. Сегодня, во-первых, у нас немножко такой особый урок в формате интенсива, а в отличие от вебинаров в Otus, которые длятся полтора часа, спокойно, с чувством, с толком, с расстановкой. Сейчас мне хочется дать вам максимум за тот час, который у нас с вами есть. А, поэтому, конечно, буду широкими мазками вам про это рассказывать. Вот. А потому что хочется, чтобы вы ушли и с пониманием того, что такое парсинг, как его делать и какие инструменты для парсинга вы можете применять, чтобы базово, а, большинство сайтов успешно обкачивать, да, хочется дать вам такой хороший гайд, туториал и инструмент.
А помимо всего прочего, у нас с вами немножко особая платформа — это Life Digital. Она отличается от той платформы, на которой мы будем работать в Otus. В Otus мы работаем на вебинарах MTLink. Там вы можете включить микрофон, задать вопрос голосом, группы небольшие. Здесь же у нас немножечко отстранённый формат. Вот. Но я надеюсь, что нам это совершенно не помешает проводить открытый урок. И, а будет здорово, если вы будете активно участвовать. Задавайте вопросы. Я их вижу не сразу, только когда переключаюсь на чат, но я, а буду регулярно делать паузы и как раз-таки в чате всё-всё-всё смотреть. Тогда у нас с вами получится максимально продуктивный вебинар. Ну и про запись я, на самом деле, сказала, но на всякий случай, ещё раз повторю, запись идёт, я выложу в Telegram-канале Машка про Data Science. Там же рассказываю про всякие ивенты и, а, дополнительно она придёт вам на почту, если вы зарегистрировались.
Итак, а, собственно, пару слов скажу про Otus. Что это за, а, образовательный онлайн-проект для тех, кто с нами здесь впервые. Кстати, если вы проходили курсы в Otus или ходите на мои открытые уроки, тоже сигналите в чат, а, чтобы я понимала, новички здесь в плане обучения Otus или уже завсегдатаи наших курсов или открытых уроков. А, собственно, для тех, кто Otus ещё не знаком, пару слов про это скажу. Otus, а, по сути, специализируется на курсах для IT-специалистов самых разных уровней, от джуниоров до синьоров и тимлидов. Что круто, программы, а, разрабатываются на основе актуальных и самых последних запросов IT-компаний и кандидатов. Я сама работаю в Сбере с моделями и стремлюсь, чтобы та практика, которую вы будете щупать руками на занятиях, она вот соответствовала тому, что мы реально делаем. Вот привела живой пример. Сама как раз вчера с коллегами обсуждала нашу парсилку сайтов, которая суть такая же, как мы сегодня будем разбирать на открытом уроке, да? То есть на курсе мы постоянно обновляем, актуализируем материал в связи с быстрым прогрессом, а, и стремимся, чтобы был максимально прикладной и полезный для тех, кто увлекается LLM и NLP.
Помимо всего прочего, очень хочется, чтобы вы не только научились писать код, ведь, а, написание кода мы во многом можем делегировать нейронным сетям сегодня, чтобы вы понимали, что за этим кодом стоит. Могли действительно вникать, анализировать и за счёт именно общего глобального знания того, как это устроено, а находить крутые решения. Это как раз та функция, которая остаётся за нами, за разработчиками — понимать, как это устроено, понимать ту самую kill-фичу. Именно это у нас сейчас не отнимет ни один. Вот. А всю ненужную рутину мы, да, действительно скоро сможем делегировать курсору. Поэтому очень хочется, чтобы вы как раз-таки овладели в первую очередь теми навыками, которые будут актуальны и востребованы в дальнейшем с развитием AI.
Помимо всего прочего, у Otus есть образовательная лицензия, бонус, мелочь, приятно. А, и по окончании программы вы получите удостоверение либо о повышении квалификации, либо диплом о переподготовке. Да, и, а, на самом деле Otus — это не только про машинное обучение, не только про Data Science, не только про мои курсы. Всего, а, на платформе их более 130. Вдумайтесь в эту цифру. 130 курсов по самым разным направлениям: программирование, безопасность, управление, архитектура, Data Science, аналитика, анализ, инфраструктура, DevOps, тестирование. Залетай на платформу, как говорится, выбирай, что подходит именно вам. Я, кстати, многих руководителей знаю лично и могу аа многие курсы вам смело порекомендовать. Приходите к ним на открытые уроки, а, записывайтесь на то, что интересует именно вас.
А сейчас я переключусь на чат, посмотрю, что вы пишете, и после этого мы перейдём уже к теме нашего занятия, а именно к парсингу сайтов на Python. Ой, не туда всё время залетаю. Так, Александра, да, да, я их вижу. Кстати, по-моему, ты была на предыдущем открытом уроке. А так или нет? Я вижу сообщение в чате, так что всё хорошо. Ага. Выпускник ли Adвенс. А, всё, вспомнила, конечно. Привет, Гренобль в Альпах. Как там, кстати, погода? Хочу разобраться с парсингом. Хорошее желание разобраться с парсингом, потому что очень актуальная вещь. Даже если с LLM-ками, с NLP вы не будете так дальше работать, то парсинг сайтов пригодится точно любому ML-щику и не только. Так.
Что ж, вижу, что аудитория сегодня очень мотивированная, заинтересованная, и не будем тянуть быка за рога. Перейдём сразу к теме занятия. И сегодня мы, а, поговорим про то, как устроены сайты, как их парсить. Посмотрим, какие вообще существуют, а, инструменты парсинга на Python. И сразу такой небольшой спойлер. Инструментов парсинга у нас великое множество, на самом деле. А у меня нет цели сегодня рассказать вам, а, про все, потому что тогда я просто их перечислю и зачитаю по списочку, как мне кажется. Ну, максимум пару предложений про каждое скажу. А мне хочется дать вам два классных хороших инструмента, просто обрисовав, что есть, например, ещё и другие, да, такие как Selenium. Ну, зная базовые, вы дальше любые другие очень легко освоите. Вот. А зато эти вы уже, а, освоите на таком уровне, что сможете с их помощью сайты собирать. То есть мы сегодня работаем на результат. Результат — научиться парсить сайт. И, конечно же, у нас сегодня будет очень много практики. А по сути, сегодня такой акцент именно на неё. Теории будет буквально несколько слайдов, по которым мы сейчас и пойдём. И по сути, после сегодняшнего вебинара вы, а, поймёте, что, где, зачем и как, какие существуют библиотеки для парсинга сайтов на Python, как это делать и зачем это, собственно, вам. План буран. Планов на сегодня много. Погнали.
Зачем же парсить сайт? Прошу прощения, кстати, за голос. Аллергия на цветение. А, обожаю цветы, когда вот это всё цветёт. Ну, есть один нюанс. Вот. Поэтому прошу прощения за такой голос. Вот. Но я надеюсь, это совершенно не помешает нам. Главное, демонстрация не отваливается, как, а, часто бывает в Life Digital. А, итак, начнём с того, зачем нам парсить сайты, а, а, и, а, для чего это бывает нужно. Часто мы, а, хотим собрать какие-то данные. Возможно, у нас уже есть небольшой датасет, но нам этого не хватает. Или мы понимаем, что датасета у нас нет, но данные есть в открытом доступе в сети. И чтобы нам обучить модель, нам нужно эти данные собрать. А зачастую, а, данные даже не запрещено скачивать, но, а, практически никто из разработчиков сайтов не задумывается об ML-щиках, которым эти данные могут быть нужны. И мало кто делает такую хорошую кнопочку "Экспорт CSV" и позволяет со своего сайта выгрузить дамп со всей информацией. К счастью для нас, например, Википедия такие дампы регулярно предоставляет, но не все такие хорошие, как Википедия. И, а, зачастую есть очень много открытых, например, статистических данных, а, а, с информацией о там финансах, которые в открытом доступе абсолютно есть, они доступны. Но, а, бытовой пользователь их может разве что Ctrl+C, Ctrl+V. А, соответственно, нам, поскольку не хочется работать руками, а гораздо, конечно же, удобнее написать небольшой парсер на Python, который бы эту информацию, а, нам услужливо бы на тарелочке преподнёс, то есть скачал. А по сути, таким образом мы можем пополнять и расширять наши датасеты для обучения, да, просто автоматически собирая данные из интернета и тем самым создавая уникальные тренировочные наборы на реальных данных, которые есть.
А помимо этого мы можем обогащать данные, а, интегрируя тогда информацию с каких-то веб-ресурсов, а, агментировать данные, повышать их качество, а, и создавать базы данных для того, чтобы современные LLM, а, обладали фактологией. Это так называемый подход RAG, когда мы инкорпорируем фактологию в современные модели через то, что мы разрешаем модели обращаться к некоторой внешней базе данных, так называемой базе знаний. Вот, чтобы эту базу знаний собрать, возможно, нам как раз-таки понадобится парсер на Python. Да, это, кстати, может быть использовано помимо просто в классической аналитике данных, да, например, для анализа рынка, конкурентов, прогнозирования спросов и трендов и мониторинга обновления, отслеживания, например, тех же изменений на веб-странице. То есть, видите, я сейчас вот так сходу по щелчку уже вам четыре, а, таких больших направления, где это может применяться, назвала, но их, конечно же, гораздо-гораздо больше. А сейчас посмотрю, что происходит в чате. О, Александр, привет, рада видеть. Как раз ты пока ничего не пропустил, точнее, пропустил вводную, общую вещь. А мы как раз уже переходим к тому, чем же мы будем парсить. И, конечно же, как истинные ML-разработчики, парсить мы будем в первую очередь Python. А, и как я уже сказала, инструментов для парсинга на Python существует множество. Из таких, а, на слуху наиболее библиотек — Beautiful Soup и Selenium на Python. Selenium он по сути эмулирует браузер. А, классный инструмент. Вот. Но у него есть свои нюансы. Сегодня же мы будем работать с Requests и Beautiful Soup, а, такими самыми надёжными, а, рабочими лошадками парсеров, а, очень удобными и, главное, а, с ними, а, как бы что-то может случиться в последнюю очередь. Мне эти инструменты очень нравятся. Как раз-таки сегодня своим опытом я поделюсь.
А если говорить про то, а что же такое сайт, то сайт — это по сути, а, HTML-код. А, а, и, а, когда, собственно, мы хотим спарсить HTML-страницу, мы делаем HTTP или HTTPS запрос. А, по соответствующему URL-адресу. HTTPS отличается от HTTP, а, только тем, что это зашифрованные данные, поэтому смотрим на примере HTTP. И в ответ нам приходит, а, а, собственно, код страницы. А чаще всего у нас всё хорошо, и мы, а, получаем данные вместе с кодом 200, что говорит нам о том, что действительно запрос успешно получен. Данные у нас в кармане. Однако, а, не всегда бывает так. Все абсолютно, кто когда-нибудь работал с интернетом, видели ошибки типа 403 "Доступ запрещён" или 404 "Ресурс не найден". То есть коды, которые начинаются с четвёрки, сообщают об ошибках на стороне клиента, а коды, которые начинаются с пятёрки, об ошибках на стороне сервиса. Помимо этого у нас возможны перенаправления и информационные ответы. Информационные ответы очень редкие. Вот ошибки, а, типа 404, 403, они действительно встречаются. Даже если с сайтом всё хорошо, мало ли, вы неправильно случайно ввели URL.
А как же теперь парсить? А, всё просто. Нам нужно понять и разобраться, что же представляет из себя любая HTML-страница. И по сути, конечно же, когда мы открываем HTML-ку, а, в браузере мы видим красивое расположение картинок, красивый отформатированный текст, но в реальности это, а, в голом виде выглядит примерно так. А, соответственно, такая вот мешанина из тегов и, а, которая описывает, где расположить тот или иной элемент. По сути, это то, как видит HTML наш браузер. И дальше, исходя из вот этих вот рекомендаций, записанных в виде тегов, наш браузер понимает, где и какой элемент ему необходимо расположить. И опираясь уже на эту информацию, он, соответственно, рендерит. Отсюда и бывает, что один браузер показывает эту страницу так, другой так. Он просто браузеры интерпретируют, да, какие-то, а, не очень хорошо прописанные теги, немножко по-разному, да. Если говорить, кстати, про расшифровку HTML, не все её знают, а, то расшифровывается это как HyperText Markup Language, а, по сути, язык гипертекстовой разметки. А, что-то типа Markdown, но для сайта. Вот сегодня, а, а, чаще всего говорят, конечно же, HTML, не заморачиваются, но главное, что это такая, а, древовидная структура тегов, которая описывает все-все-все элементы на сайте. Ну, какие теги там бывают? Например, тег `<a>`, который используется для создания ссылки, теги, связанные с заголовками `<h1>`-`<h6>`, тег `<span>`, который представляет, а, детей, а, `<div>` — разделение и так далее. На самом деле, запоминать все теги вообще не обязательно, а, потому что при работе и при парсинге вам важно будет понимать, какой тег соответствует какому элементу на сайте. Это для этого знать, а, название тега не нужно, да? Главное — это уметь посмотреть в обе. Вот. Ну и, конечно, если вы будете, а, очень много работать с парсингом, вы будете постепенно развивать свою насмотренность и какие-то базовые теги знать. Но опять-таки, подчеркну, что это абсолютно необязательно.
И, соответственно, когда мы будем парсить, мы будем открывать сайт с интересующими нас данными, а, находить на этом сайте интересующий нас элемент в браузере, а, жать правой кнопкой мыши или если мы на Макбуке, то двумя пальчиками и смотреть, какой тег окружает тот или иной элемент. Для этого, а, в контекстном меню, которое вызывается по правой кнопке мыши, обычно есть, а, а, опция типа "Посмотреть код элемента", "Код элемента", "Inspect element" код. Точная формулировка этого названия зависит от браузера, но это точно что-то связанное с кодом, и это позволяет вам посмотреть сырой HTML, где будет подсвечен тот элемент, который вы хотите, собственно, найти. А дальше вы берёте, а, общий HTML в Python-чике, а, с помощью как раз-таки этого тега находите интересующий вас элемент, оборачиваете это в библиотеку Beautiful Soup и дальше, а, библиотека Beautiful Soup сделает всё за вас. Кстати, а, библиотеку называют часто "суп" или "супчик", потому что её лейбл — это "Алиса в стране чудес", и называется она Beautiful Soup. Суп — это мыло, но на русский манер в "Алисе в стране чудес" они варят красивый суп. И поэтому названием библиотеки на русском тоже часто, а, сокращается до "супчика" или "супа". Вот. Не пугайтесь, это просто такой же организм тех, кто много работает с парсерами сайта.
Что ж, теории, как я говорила, будет не очень много, а, потому что самое главное в парсинге — это практиковать. Давайте это, собственно, и сделаем. И сегодня мы будем, а, практиковать парсинг вот этого сайта. А, называется он Books to Scrape. Сейчас скину вам ссылку на сам сайт, который мы будем парсить, и, а, практику на Google Colab. А практику на Google Colab я ещё дополнительно выложу потом в своём Telegram-канале. Ну, давайте сначала посмотрим, как мы можем посмотреть сырой код HTML-страниц. И для этого перейдём как раз-таки на сайт с книгами, которые мы будем обкачивать. Вот я нажимаю контекстное меню, а, и у меня здесь есть опция "Посмотреть код". Я её вызываю. Вот мне показывается, что это находится в `<img>`, да? И здесь как раз-таки прописано, что это за имидж. И дальше дополнительно вся информация. Можно чуть повыше взять, что это, а, класс `image-container` и, например, по нему вытаскивать вместе со всей сопутствующей информацией. А, вернёмся к практике. А сегодня мы ворвёмся в это хранилище книг, в эту библиотеку и соберём оттуда основную информацию о книгах, которая там есть. Что это за информация? Названия, рейтинги, цена, наличие на складе, категория и дополнительный код. Кстати, из интересных моментов, а, обычно парсер, а, разделяют на несколько частей, а, иногда можно услышать такие слова, как краулинг и скрейпинг. Краулер — это часть парсера, которая, по сути, бродят по ссылкам, да? Потому что, чтобы обкачать сайт, нам надо, а, по ссылке на каждую книгу перейти, да, вот так вот, хоп, перейти и дальше информацию про книгу посмотреть. Вот, собственно, краулер — это, по сути, такой паук, паучок, который ползает по вот этим вот ссылкам. А скрейпинг — это непосредственно часть парсера, которая собирает информацию с самой страницы. А, соответственно, парсер — это сразу и краулинг, и скрейпинг, два в одном. А, ну, в принципе, можете не париться, просто говорите "парсинг", вас поймут. Вот. Главное, чтобы, если вы услышите "краулер", "скрейпер", вы не пугались и понимали, о чём, собственно, идёт речь.
Что ж, а, давайте сделаем наш первый запрос. Подгрузим для этого основные библиотеки. А, и сегодня нам помимо стандартных нам Py Pandas понадобится ещё библиотека Requests. Она позволит нам как раз-таки делать запросы на сайты и собирать оттуда информацию. Введём, а, стартовую ссылку, а, для нашего сайта, с которой мы будем всю информацию собирать. И сразу не будем показывать серверу, что мы сидим на Python. Замаскируемся под невинного пользователя, чтобы сервер нам не закрыл доступ. И очень часто так бывает, что сайт даже не запрещает себя обкачивать, но для автоматических запросов они закрывают доступ просто потому, что боятся DDoS-атаки или боятся какого-то излишнего количества запросов. Вот. Но чтобы это обойти, а, избежать таких самых базовых блокировок, есть замечательная библиотечка. Называется она Fake User Agent. Она абсолютно открытая, законная. И там есть класс `UserAgent`, который позволяет нам эмулировать работу разных браузеров. Вот можем прикинуться, что мы сидим, например, из-под Chrome или из-под Safari. Кто хочет, может там и Opera взять, кому что ближе. Поставьте здесь то, что нравится, как говорится, именно вам.
После того, как вы прикинулись, что вы сидите из-под браузера, давайте сделаем наш первый запрос. И, а, здесь нам метод `requests.get` в помощь. Он по сути, а, идёт по тому URL, который у нас есть здесь, в данном случае будет вот эта вот страничка наша основная. А дальше в качестве хедера мы указываем, что мы пользователь, который сидит из-под Chrome. Я, кстати, сейчас под Chrome, так что здесь всё честно, скажем так. И, а, можно посмотреть, а, какой у нас пришёл ответ. Если мы посмотрим на тип этого response, то это специальный класс библиотеки `requests`. И мы видим, что это 200. А вы помните, что 200 — это, напишите, пожалуйста, в чат, что означает `response` 200. Помните, у нас был про это слайд. Успешно. Молодцы. Абсолютно верно. Это успех, товарищи. А, а, соответственно, сайт, а, выдал нам информацию, и давайте попробуем на эту информацию посмотреть. Возьмём `response.text`. И увидим что-то неудобоваримое от слова совсем. Становится страшно даже мне. Волосы, можно сказать, дыбом встают. Что это такое? Абсолютно непонятно. Давайте посмотрим. Может быть, там в начале какая-то абракадабра, дальше станет лучше. Посмотрим на последние тысячу символов. Видим, что лучше точно не стало. Возможно, стало даже ещё печальнее. И если мы посмотрим на длину всего этого безобразия, то станет ещё хуже, потому что длина всего этого безобразия — 51 000. И это даже не символы, это байты. То есть сейчас у нас какая-то махина из 51 000 байт, с которой непонятно что делать. Вот. И тут нам на помощь как раз-таки приходит библиотека Beautiful Soup, которая позволяет нам сварить из-за всего этого неудобоваримого читаемой штуки, а, красивый супчик.
Загрузим, а, собственно, класс `BeautifulSoup` из пакета `bs4`. И дальше, а, обернём наш HTML-документ как раз в Beautiful Soup с помощью `HTMLParser`. Да, теперь мы видим, что у данного элемента изменился тип. Это уже элемент класса `bs4.BeautifulSoup`. А, например, его можно вывести в чуть более красивом виде и увидеть действительно дерево тегов, которое у нас есть. Согласитесь, стало куда приятнее. Мы видим уже какую-то структуру нашего HTML. Что ещё? А теперь, помимо того, что это стало чуточку приятнее глазу, а, мы получили на самом деле распаршенное дерево тегов. Это то, что как раз-таки круто, потому что теперь мы по этому дереву тегов можем бродить. Можем, например, взять заголовок, да, просто спустившись вниз до `title`. И видим здесь "All products book to scrape". Внимательный, а, слушатель может заметить, что это в точности вот этого вот заголовок, который вот здесь написано "All products book to scrape". Да. И вы видите, что мы можем вот так вот спускаться и вот, например, посмотреть всё, что входит в `header`, да? Вот здесь гораздо больше информации, чем просто в заголовке, да? Можно просто весь HTML посмотреть и так далее. А тип у вот этого заголовка тоже элемент с классом `Tag`. А можно вытащить из этого места, в которое мы зашли, а, текст, просто обратившись к атрибуту `text` у вот этого тега. И дальше этот текст имеет смысл ещё дополнительно обрезать от лишних пробелов. А, такая классическая постобработка зачастую в парсинге бывает нужна. Да. Теперь это обычная строка. Вот этот вот, а, кусочек "All Products Book to Scrape", который мы видим в точности именно здесь.
Более того, зная адрес конкретного элемента, мы сразу можем найти его. Например, мы это можем сделать по классу. И, а, вызвав метод `find`, который как раз-таки и позволяет нам всё искать, мы можем сказать: "Найди нам, а, что-то с тегом `div`, у которого будет класс `site-categories`". И, соответственно, мы в точности находим боковые категории. Это вот эти вот категории, которые здесь есть. Можно, например, дальше на них обкачать ссылки и дальше для каждой категории собирать с ссылкой на книги, которые тут есть. А либо, кстати, если мы хотим собрать все книги, мы можем просто вот здесь странички листать постепенно и как раз-таки страничка за страничкой всё обкачивать. Мы сегодня пойдём, кстати, по второму путину дома. Если захотите попрактиковаться, можете как раз первый посмотреть. По работе с классами при этом нужно быть внимательным, потому что, а, например, если мы попробуем найти класс `header`, то мы, а, получим как результат все элементы, где содержится упоминание хедера. И, например, если класс у нас `header-container-fluid`, то, а, в том числе этот объект под наш `find` попадёт, потому что `find` по сути проверяет вхождение. А если нам нужно точное совпадение, то я рекомендую писать более детерминированно. Выглядит это, может быть, чуть менее красиво, но в парсинге главное, чтобы мы случайно не сломались на каком-то крайнем случае. Поэтому я всегда за то, чтобы здесь писать максимально надёжно, пусть даже, возможно, где-то и избыточно, но за то, чтобы это точно не сломалось и давало вам тот результат, который вы хотите, да, в данном случае, а, уже, а, вот такой результат вам точно вернёт в точности класс `header` и больше ничего. А полученный после поиска объект также может обладать структурой Beautiful Soup.
И мы, например, можем посмотреть, что здесь у нас есть ссылка Books to Scrap, а с индексом HTML. Это, по сути, мы сейчас взяли главную категорию Books, а и из боковых категорий. И если мы посмотрим на требуют гиперссылка, то это индекс HTML. Дело в том, что здесь ссылки хранятся в укороченном виде без вот этой вот, а, без всего того, что да.com. А когда мы переходим на родную страницу, то здесь точность получается адрес HTML.
А обратите внимание, кстати, что после вот этих вот преобразований безумных, которые мы сделали, теперь у данных поменялся тип. Если раньше это был элемент best4 типа тег, то теперь это просто строка. А если несколько элементов на странице подходят под наш find и мы хотим найти их все, то здесь нам find не поможет. Нам понадобится чуть более мощный метод, а именно метод find. И давайте как раз-таки попробуем его применить и найти всё, что обладает тегом. А применим и посмотрим. Как раз в точности получили ссылки на боковые категории, а всего их 94. Даже достаточно много, кстати.
Что можно дальше сделать? Их можно дальше, конечно же, почистить, потому что сейчас, видите, здесь как бы это объекты. Давайте-ка посмотрим, что это за объект. Это объект типа тег. А, а мы захотим выключить отсюда, а-а, ссылки на конкретные категории. И давайте это сделаем. Для этого просто пройдём в цикле и возьмём соответствующие, а, линксы, а, дополнительно убрав лишние пробелы. Аа, получили нужные вещи. А, берём атрибут гиперссылок просто в циклике и получаем вот такой набор боковых категорий, с которыми мы можем дальше работать. А мы получили все ссылки с главной странице. Теперь всё готово, чтобы собрать ссылки на каждую конкретную книгу.
И ещё раз, это можно сделать двумя способами. Первый, через общий раздел книги, где сохранены все книги. То есть это вот это вот all products. А здесь, соответственно, мы можем просто листать с первой по пятидесятую страничку. Обратите внимание, когда мы листаем, мы по сути в URL просто меняем номер страницы. Это такой типичный кейс. На самом деле для большинства сайтов, которые мы парсим, как раз-таки смена страничек заключается в том, чтобы URL грамотно поменять как раз-таки, а, соответственно, чтобы номер где-то, который в этот URL на самом деле зашит, поменялся. А либо мы можем пойти вторым способом через раздел отдельных категорий книг. А, ну тогда нам тоже иногда придётся листать. А, поэтому, чтобы дополнительно не париться, не делать вот этот вот шаг по боковым категориям, просто пойдём по всему, будем страница за страницей листать а наш сайт и обкачивать книги с каждой страницы. А для того, чтобы как раз-таки листать страницы, мы не будем пытаться эмулировать браузер через селениум, не будем пытаться жмакать кнопку Next. Мы просто будем листать страницы, меняя номер, потому что это на самом деле page 1, page 2, page 3, page 4. Да, ещё раз, если у вас есть какой-то другой сайт, там вот эта вот кодировка номера страницы может быть по-другому записана. Не через page, а через ID равно 1. Может быть здесь вопросик один. Да, но вам главное полистать страницы и попробовать выявить закономерность либо спросить у какой-нибудь, кинув несколько адресов, типа, проанализируй эти URL и скажи, где здесь номер страницы. Справится, скорее всего, вот так.
А что ж, давайте теперь, а, по модулю всех тех знаний и всего того, что мы обсудили, напишем такую функцию, назовём её getook pages. А, соответственно, она по просто номеру страницы будет с этой страницы собирать все ссылки на книжки, которые там есть. А, всё очень просто. А, на вход принимаем просто циферь in. А дальше подставляем эту цифир в URL, а в нужное место, где как раз-таки стоит номер страниц. Это абсолютно нормальный способ для парсинга, как нам переключать страницы. Самый простой и, как я уже говорю, простой, надёжный, то, что нужно именно нам в парсинге всегда простота плюс надёжность. Отличное комп. Дальше делаем запрос. Не забываем эмулировать, что мы сидим из-под хрома. Ну, как я сказала, можете сидеть из-под Safari или из-под чего-то ещё. А потом проверяем, что responsнс о'кей. Это, кстати, очень важно. В подобных системах вообще всегда важно, а, скажем так, важна отказоустойчивость. Что-то может пойти не так. Конкретно в моменте сайт не выдал вам ответ, не знаю, там моргнул, у вас там что-то с интернетом, да, чтобы всё не упало, да, и, например, конкретная страница пропустится, ну и ладно с ней. Поэтому всегда проверяйте и делайте план Б на случай, если что-то пойдёт не так. Наш план Б, если какую-то конкретно страницу мы не обкачаем, вернём пустой список. В противном же случае мы уже знаем, что делать, а собираем всё то, что мы обсудили, в остаток нашей функции. Берём content, если всё о'кей. А оборачиваем content beautiful sub. А с помощью метода find all находим все места, где у нас фотки. И дальше из-под фоток нам нужно вытащить а ссылки, да, опять-таки, а как мы понимаем, где у нас фотки? Вот смотрим код элемента, видим, что у нас здесь фотка и чуть выше класс имиage контейнер, который в точности и содержит вот эту вот ссылку на конкретную книгу. Соответственно, нам как раз-таки вот этот вот а класс имидж контейнеры понадобится, чтобы потом уже в рамках вот этого кусочка нашего дерева тега мы могли быстро и просто ссылку найти. Вот нашли как раз-таки по классу фото, нашли идж контейнер и оттуда выкусили ссылку с помощью уже фай, да? А сложив её в наше Book Linkкс. Вот можно посмотреть, сколько ссылок у нас собралось, например, со страницы три. Их 20. Это, например, slow states of collapse poems reasons to stay alive. Without borders, wonder love 1956. Проверим, что это законные ссылки. И давайте просто попробуем. Возьмём вот эту вот ссылку и введём её в браузер. Что у нас будет? Введём её в браузер и что-то видим, что что-то не то. Да, если мы здесь попробуем вот просто ссылку взять. и с помощью метода request get найти, а окажется, что что-то не то. И тут мы вспоминаем, что мы забыли прибавить, а вот это вот название bookstuscrape.com. Если на самом деле мы вот так вставим ссылку, только, конечно же, без кавычек, не повторяйте кавычки. Так, сейчас не совсем точно ой-ой-ойой, не совсем точно ввела, а базовое название. Базовый префикс у нас каталог. Я забыла каталог ввести, из-за этого у меня не открылось. Если мы введём вот здесь ещё каталог и здесь уберём в кавычки, то в точности мы получим то, что а мы непосредственно хотим. То есть теперь уже эта ссылка существует. Соответственно, нам надо ко всем ссылкам добавить вот такой вот префикс. А напишем такую функцию короткую. префикс, который бы там заданный префикс по запросу добавляла. И теперь у нас всё готово, как раз-таки, чтобы по этим ссылкам ходить. Вот они даже кликабельные. Можно ещё по какой-нибудь перейти. The past never ends. Какие-то грустные здесь книжки и стоят достаточно дорого. Ну ладно, не страшно. Есть ли здесь что-то весёлое? Во, inance. Выглядит достаточно весело. Travel. А, я знаю, надо перейти в historical fiction humor. Надо в раздел юмора перейти, и тут будет уже что-то весёлое. Он hyperбов. Пока что действительно здесь уже попозитивнее. И цена гораздо позитивнее, надо сказать. Как приятно. Я люблю позитивные книжки. Кстати, напишите, пожалуйста, в чат, а какой тип жанр литературы предпочитаете вы, а я заодно проверю, что в чате всё хорошо. Драма. Ого. Ого. Эльвира, серьёзный человек. Я люблю весёлое для развлечения. Скифай. Да, я тоже люблю скифай. SciFi по разработке приходится, да? Я больше, наверное, стати читаю. Вот дописывайте, а жанр литературы, если дописываете, а мы потихоньку идём дальше.
Теперь давайте соберём, а ссылки на все книги со всех страниц. Вот сейчас, чтобы не ждать, а соберём, а, по сути, пройдём по страничкам. И а пока мы не упрёмся в то, что у нас странички перестанут существовать, да, если мы просто достаточно долго будем кликать вот здесь, да, например, поставим здесь, я не знаю, страничку 60, то мы увидим, что у нас в какой-то момент просто книжки закончатся и будет ошибка. Поэтому вполне законно вот такой цикл true, он точно закончится, потому что когда мы дойдём до шестидесятой страницы, мы точно упадём. Пока же мы не упали, мы, соответственно, будем просто постепенно страницы за страницей эти страницы обкачивать и их сохранять. А дополнительно на всякий случай обезопасим себя от ошибок. Если первый раз страница какая-то не прошла, мы её пропускаем, но уже после трёх пропусков мы делаем стоп. Да, опять-таки, это такая хорошая рекомендация для случая, когда а у нас что-то в какой-то момент с какой-то конкретной страницей пошло не так, чтобы у нас с одной стороны всё не упало. С другой стороны, если мы видим, что у нас ошибки стали систематические, например, всё, мы дошли до конца или там соединение прервано, мы бы, а, непосредственно не продолжали в бесконечном цикле крутиться и пытаться спарсить. После такой обкачки у нас с вами получилось 1.000 ссылок на книги. И, кажется, это уже такая неплохая библиотека там на несколько лет почитать. А, финальная подготовка к грабежу. Я надеюсь, вы готовы.
Теперь нам нужно уже непосредственно с каждой конкретной странички спарсить информацию, которая здесь есть. Давайте рассмотрим на примере всё-таки юмора. Я не могу что-то грустное, я юмор хочу. Вот возьмём kit. Long hold of kit. Потрясающе. А, соответственно, на примере вот этой страницы мы будем парсить, собирать название, а, в наличии или не в наличии, количество звёздочек и основную информацию. Да, дома, кстати, можете попробовать научиться, например, ещё дополнительно а картинку сохранять. по аналогии со ссылками, а, соответственно, открываем страничку с книгом, а, будем находить соответствующие теги и всё, получаем профит. Соответственно, давайте вытащим из книги её название, рейтинг, стоимость, наличие. Пока, кстати, будем смотреть только в наличии или не в наличии, но дома можете расширить пар и попробовать количество как раз-таки доставать. А, жанр, код и ссылку. UPS-код - это вот, знаете, как код товара на WBR или Оzone. Только для вот этого конкретного сайта. Первое, что мы делаем - это собираем основную часть с информацией. И дальше, смотрите, опять-таки у нас страницы могут быть разной степени заполненности. Здесь сайт хороший, про все информации у нас всё практически есть. Но вдруг вдруг такое случится, что где-то, например, не будет названия, где-то не будет проставлен рейтинг. То есть здесь опять-таки такого практически нет, но на других маркетплейсах такое вполне может быть. Поэтому всегда в парсинге нужно а помнить про план Б. Например, здесь мы будем проверять, если у нас нету названия, пишем incognite. Если название есть, парсим его. А, соответственно, дальше собираем рейтинг. И рейтинги, на самом деле, они записаны в виде слов, сколько там звёздочек. И мы эти звёздочки преобразуем, а, и просто по названию количеству звёздочек в тот рейтинг, который нам нужен. 1 2 3 4 или 5. Если опять-таки рейтинга нет, да, вспоминаем, откатываемся назад, то ставим -1. А цена, следующая немаловажная вещь. Находим по по классу Price Color. И опять-таки, если не нашли, то у нас есть план Б. Ставим 0. В данном случае мы сейчас для всех будем ставить, что не в наличии, но дома как раз вам задачка. Соответственно, для того, чтобы понять, сколько в наличии, во-первых, нужно посмотреть код элемента, понять, какой код этому соответствует. Вот он, да, как раз. А, найти класс instilability и дальше внутри этого класса выкусить количество, да, то, что в скобочках, соответственно, взять до первого пробела, это и будет количество в штуках, которые у нас есть и которые потенциально мы можем купить. А, соответственно, дальше выкусываем категорию и, а, UPS, то есть код товара. Для того, чтобы выкусить код товара, нам нужно будет вначале собрать а табличку. Это ведь на самом деле табличка, просто она так отформатирована красиво. А так вообще table, да? Соответственно, мы как раз-таки ищем table к table table stript. И там, а, соответственно, вначале итерируемся по колонкам, а потом по столбцам. Находим нужное нам место и из этого места забираем UPS-код. Соответственно, всё, что мы получили, можем сложить вот такой словарик. А теперь у нас всё готово, чтобы обернуть это в итогу и парср, но поскольку пар дело непредсказуемое и выдаёт очень неоднородную структуру, не забываем, во-первых, про план Б и про траэксепты, которые нам позволяют, опять-таки лишних падений, а, за ненадобностью этих падений избежать, потому что нет, нет, даже если всё корректно, где-то там что там сигнал не пройдёт. А, соответственно, ура, наконец, всё готово, чтобы финально собрать функцию getта. А, но перед этим ещё раз проверю чат. Ой, Азимов, обожаю Азимовач. Я читаю чат. А здесь вы пишете про своих любимых авторов. А, Азимова обожаю. У Гоголя, кстати, да, тоже что-то есть. Я, ой, прошу простить, я из наших люблю Гоголя и Пушкина. Вот. Интересный набор у меня. Лермонтова, кстати, меньше. Ну, из вот золотого века, а из серебряного тоже многих люблю.
Итак, а getbook data. Пишем функцию. Она будет запрашивать данные с нашей страницы и возвращать нам на выходе обработанный словар с данными. А, соответственно, делаем для конкретной страницы запрос. Не забываем указать, что мы сидим из-под Фрома. Если запрос прошёл и всё о'кей, мы берём contentт, берём content, оборачиваем это в beautiful sub и дальше уже имеяха на руках fн for get stats, забираем оттуда всю необходимую информацию. Дополнительно к информации прикрепляем URL. Вот это тоже, кстати, очень хороший тон. Не забывайте сами URL, а саму метунформацию какую-то сохранять. Она, а, тоже очень нужна. Дома можете попробовать ещё дополнительную категорию книги добавить как важный метод информации. Соответственно, проверим, что это работает, запустим функцию. Да, мы собрали информацию о Slow States Collapse of Poems. Нет, я не хочу про эту грустную книгу собирать информацию. Давайте возьмём информацию про вот эту книгу. Она гораздо интереснее и приятнее. Да, собрали наш Long Hold da of Kit. Рейтинг один. Ладно, вряд ли она интереснее. У неё рейтинг один. Давайте что с хорошим рейтингом спарсим. Вот. Неужели это юмор? Во, вот это классно. Вот это мне кажется хорошее. Да, госпокорн. Интересный набор, конечно. Ладно. Вот old school. Вот это уже тоже аа вторая часть с пятизвёздочным рейтингом. Вот это мы сегодня возьмём. Это нам подойдёт. А Спарселя хорошую книгу с хорошим рейтингом. Пять. Стоит она 1133. Ещё и цена приятная. Да. в наличии категория юмор. А теперь, соответственно, на основании этого а подготовим табличку, куда мы будем записывать всю информацию о тех книжках, которые мы нашли и добавили в нашу библиотеку. Собирать будем в Pandas Dataфame. Опять-таки Pнes Dataфame сейчас, потому что у нас данных не очень много. Если у нас будут огромные тексты, то разумнее, конечно, использовать какой-то другой экономичный текстовый формат, кста, например, или что-то ещё. Получили вот такую вот вещь. Первая книга в наших руках. Ура!
Теперь давайте пройдёмся по нашему списку ссылок. У нас уже есть, а, Booklinks. Напомню, их 1.000 штук. Это вот такой вот список огромный из книжек. И дальше мы просто в цикле идёмся по этому списку из книжек. А, и для каждой книги повторяем то, что мы уже знаем, как собирать. А, вызываем get book data. А, проверяем, что у нас всё хорошо, что всё конвертировалось. Опять-таки, на всякий случай, мало ли что. И добавляем нашу финальную датафрейм. Хороший тон после каждого запроса спать какое-то время, а, чтобы опять-таки сайт нас не забанил попи, потому что сайты перестраховываются, они сами боятся не выдержать нагрузки и поэтому зачастую ограничивают трафик с одного пи. Поэтому хорошим тоном считается спать. Можно, например, рандомно от одной до 3 секунд спать, можно полсекунды спать. 0,3 маловато, обычно там 0,5 хотя бы, либо какой-то рандом, чтобы у нас нерегулярные были запросы, и это как бы ещё лучше позволяло нам прятаться. Вот блокировок. Не забываем, а, делать возможность на случай, если какие-то ошибки. И опять-таки хорошая рекомендация, если несколько ошибок подряд, это значит, что кажется, что-то пошло не так, да, и процесс надо остановить. На всякий случай выкинем дубликаты, если они получились. И видим, что мы сейчас спарсили 21 книгу. 21 просто потому что я для экономии времени здесь не весь цикл запустила, а по двадцати. Плюс у нас уже одна книга про аа дневник Вимпикида была. Соответственно, получили 21. Вот такой вот небольшой старт нашего парсера. Вот дальше дома вы можете продолжить, опять-таки расширить, посмотреть, как скачивать картинки. Но самое главное инструмент, как парсить, я вам дала, да, помните, заходим на сайт, понимаем, какой код чему соответствует. Вот сегодня можете HTMLку вм закинуть, она вам ещё подскажет. И прописываете, как это собрать с помощью реквест. Дальше оборачиваем это в суп, а суп это всё дальше сделает за нас. Оставлю демонстрацию крана, чтобы переключиться дальше на платформу и посмотрю, что вы пишете в чате. Сейчас демонстрация остановилась. Так, задумано в чате. Пока ничего. А если появились вопросы по, а, по занятию, готова на них ответить. А я пока вам скину ссылку на наш курс, в рамках которого проводится открытый урок. Так, Александра, отправишь ссылку в чат на ноутбук в Telegram-канал. В Telegram-канале завтра будет ноутбук. Вот когда будет запись? Давай так сделаем. Вот я тебе её обязательно скину. Вот. А, соответственно, курс по обработке естественного языка, я сейчас продолжу шерить экран. Вот выглядит вот таким вот образом. А можно его тоже, кстати, спарсить. Всю информацию можно посмотреть. Ход. У нас уже профессионально проснулась. Да, давайте парсить. Когда учишься парсить, дальше это такая классная, приятная, с одной стороны, рутина, с другой стороны приятная работа, в отличие от вас не с данными, что хочется спарсить всё. Ну нет, а моя задача теперь рассказать вам про курс. Он стартует уже совсем скоро, аа, 27 мая, а, и длится 3 месяца. То есть это такой интенсив по основам Natural Language Projecting LLM. Курс проходит два раза в неделю. Наши дни - это понедельник и среда. Занятия начинаются как сегодня в 20:00, но будут они чуть длиннее, полтора часа часто с перерывом. А теория плюс практика, как правило, но зависит от занятий, да? Вот. То есть если вот этот такой же парсинг, то там будет больше практики, конечно, потому что зачем теорию парсинга сидеть и долго смотреть со слайдами? Мы в первую очередь исходим из тематики занятия. Плюс это удобная платформа MTSLink, а где у вас есть возможность задать вопрос голосом. Группы, особенно на этом курсе, как правило, небольшие, так что как раз всё отлично. Пам-пам-пам. Если говорить про программу, то а здесь мы даём вам все инструменты, чтобы вы действительно могли погрузиться в LЛ. Во-первых, а если вы а не знакомы с машинным обучением и деплонингом, то у нас здесь есть два бонусных модуля про это. И дополнительно у нас есть несколько занятий по деплоингу. Плюс мы изучаем питон как раз-таки для работы с текстами. Это регулярные выражения и работа с текстами и прочее. И после этого уже переходим к классическим методам NLP, да, говорим про векторное представление слов, про то, что такое задача языкового моделирования, а потом, а, переходим к трансформерам, которые лежат в сердце, а, современных ЛМ. А, смотрим на трансформеры, а, вплоть до методов за современными инструктивными моделями. обсуждаем инкодерные, декодерные модели, учимся их промтить и с ними работать, да, обучая, например, под свои задачи. А в конце у вас самое интересное - это проектный модуль, где у вас будет возможность попробовать свои силы для решения тех задач, которые интересны непосредственно вам. И здесь мы не даём вам заранее готовых заданных тем. Мы всегда стремимся, чтобы тема, а, исходила в первую очередь от студента. А и а если у вас, например, по работе, по учёбе есть какая-то задача, которая интересна именно вам, то, а, соответственно, а, вы можете её в качестве проекта а взять. А, и многие студенты, кстати, наших курсов NLP, NLP Advanced - это следующая уже продвинутую ступень с глубоким погружением в LM, так и делают. А, соответственно, а, соответственно, а, как раз-таки, если у вас, а, идей нет, то мы, конечно же, направим вас, но нам очень хочется, чтобы первый шаг по выбору темы сделали именно вы в первую очередь. А, и на самом деле у студентов зачастую получаются очень классные, очень мощные проекты. И это отличная возможность либо сделать какой-то проект, который вам по работе, по учёбе полезен, либо пополнить ваше портфолио проектных работ. А помимо всего прочего, у нас есть ещё замечательный а блок на Хабор. И если вы захотите, вы можете статью по итогам курса написать. Если хотите получить программу, вот сюда нажмите. Я сейчас не могу, потому что я не залогинилась. Вот. Ну, собственно, можете подробную программу по каждому модулю посмотреть. У нас, кстати, ещё здесь мы учимся о создавателе грамма бата и обсуждаем, какие бенчмарки, то есть рейтинги моделей сегодня есть. А что ж, сейчас посмотрю, есть ли какие-то вопросы по курсу. А как загружать? Для парсинга динамических страниц лучше использовать лениум. Для CSV данных просто парсите их с помощью того же реквест. Мы как раз на курсе ещё и парсин таблиц отдельно разбираем в качестве практики. Здесь мы, а, смотрим базовый парсинг, поскольку такой формат интенсива. Сколько нужно времени, чтобы научиться парсингу, Александр? Ну вот сегодня мы за полчаса научились базовому парсингу. В принципе, дальше уже дело просто практики и набивания руки. Вот для многих сайтов этого вполне вполне хватает. Вот. А скорость набивания руки зависит от конкретно непосредственно тебя. Там несколько сайтов спарсишь, и я думаю, что всё дальше будет хорошо. Возможно ли создать агенты, чтобы существовать парсинг на Питоне? Я думаю, что зависит от задачи. Можно, в том числе, попробовать это делать через агента. Вот. А, но опять-таки не факт, что агент все крайние случаи продумывает, поэтому, конечно, агенты же нужно перепроверять, а для этого нужно понимать, как устроен парн внутри. Что ж, если вопросов больше нет, то была рада вас видеть. На всякий случай напомню, а, ссылку на свой Telegram-канал, я там выложу, а, соответственно, практику. Александр, если что, напиши, а, напиши какой-нибудь комментарий, я, так быть, я пришлю, потому что даже раньше, потому что, конечно, как же без практики уже раз руки чешутся, попробовать, не могу тебя без этого оставить. Вот всем тогда хорошего вечера и я надеюсь до встречи на Эли Advance или на следующих открытых уроках. Всем пока-пока.