Написать парсер своими руками

Пишем простой парсер файлов (для начинающих)

В этой статье я хотел бы рассказать как написать простой парсер на примере сайтов aimp.ru и geekbrains.ru. Статья предназначена строго для тех, кто уже имеет базовые знания о языке программирования C# и уже написал свой первый «Hello world».

Мне всегда нравился аудиоплеер Aimp (нет, это не реклама), но встроенных скинов у него слишком мало, а заходить на сайт, смотреть скины, скачивать и пробовать как они будут смотреться на деле не было никакого желания. Поэтому я решил написать парсер скинов с данного сайта. Немного посмотрев сайт, я заметил, что скины там хранятся последовательно с присвоенным id. Т.к. до недавнего времени я знал только 1С и немного командную строку, то недолго думая я решил написать его в командной строке. Но при тестировании обнаружил, что если скачивать большое количество файлов, то во-первых часть может просто не скачаться, а во-вторых может произойти переполнение оперативной памяти. В итоге я тогда бросил эту затею.

Не так давно начав изучать C# я решил вернуться к этой идее, дабы попрактиковаться немного. Что из этого получилось читайте под катом.

Для разработки нам понадобится только среда разработки, я использовал Visual Studio, вы можете использовать любую другую на ваш вкус.

Я не буду углубляться в базовые понятия C#, для этого написано множество различных книг и отснято бесчисленное количество роликов.

Для начала запустим Visual Studio и создадим консольное приложение (т.к. мне лень делать формы нам не нужен интерфейс). Среда разработки нам сама подготовит шаблон проекта. У нас получится что-то вроде этого:

Удаляем директивы которыми мы пользоваться сейчас не будем:

И добавляем те директивы, которыми будем пользоваться:

После чего в методе Main объявляем переменную:

Парсим Aimp скины

Далее мы пишем саму функцию:

Все скины скачиваются в директорию, заданную в настройках браузера. Конструкции try/catch нам нужны для того, чтобы программа не «вываливалась» из-за ошибок. Хотя можно было обойтись и без них.

Вы могли заметить функцию GetNameOfSkin. Она нужна для того, чтобы получить название скина, который мы скачиваем. Можно обойтись и без неё, она нужна только для красоты, но раз мы только учимся, то напишем и её:

Далее в методе Main нужно вызвать скачивание на выполнение:

Парсим сертификаты Geekbrains

Сертификаты на сайте хранятся в открытом виде, и открыв их через сайт, как скины aimp мы сможем их скачать только вручную нажав кнопку скачать. Но это не дело, мы же программисты.

Тут нам на помощь приходит класс WebClient, а именно его метод DownloadFile. Ему мы просто передаем путь для скачивания и путь для сохранения и он все делает за нас. Звучит легко, попробуем сделать:

И после чего точно также вызываем эту функцию из метода Main.

Вообще обе эти функции ещё есть куда дорабатывать, но я думаю для ознакомления и самых базовых функций парсинга они вполне подойдут. Кому лень все это собирать в один проект — вот ссылка на GitHub.

Спасибо за внимание и надеюсь, кому-нибудь это поможет.

Источник

Как спарсить любой сайт?

Меня зовут Даниил Охлопков, и я расскажу про свой подход к написанию скриптов, извлекающих данные из интернета: с чего начать, куда смотреть и что использовать.

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

Чтобы спарсить данные с вебсайта, пробуйте подходы именно в таком порядке:

Найдите официальное API,

Найдите XHR запросы в консоли разработчика вашего браузера,

Читайте также:  Переходник rj11 rj45 своими руками

Найдите сырые JSON в html странице,

Отрендерите код страницы через автоматизацию браузера,

Если ничего не подошло — пишите парсеры HTML кода.

Совет профессионалов: не начинайте с BS4/Scrapy

BeautifulSoup4 и Scrapy — популярные инструменты парсинга HTML страниц (и не только!) для Python.

Крутые вебсайты с крутыми продактами делают тонну A/B тестов, чтобы повышать конверсии, вовлеченности и другие бизнес-метрики. Для нас это значит одно: элементы на вебстранице будут меняться и переставляться. В идеальном мире, наш написанный парсер не должен требовать доработки каждую неделю из-за изменений на сайте.

Приходим к выводу, что не надо извлекать данные из HTML тегов раньше времени: разметка страницы может сильно поменяться, а CSS-селекторы и XPath могут не помочь. Используйте другие методы, о которых ниже. ⬇️

Используйте официальный API

👀 Ого? Это не очевидно 🤔? Конечно, очевидно! Но сколько раз было: сидите пилите парсер сайта, а потом БАЦ — нашли поддержку древней RSS-ленты, обширный sitemap.xml или другие интерфейсы для разработчиков. Становится обидно, что поленились и потратили время не туда. Даже если API платный, иногда дешевле договориться с владельцами сайта, чем тратить время на разработку и поддержку.

Sitemap.xml — список страниц сайта, которые точно нужно проиндексировать гуглу. Полезно, если нужно найти все объекты на сайте. Пример: http://techcrunch.com/sitemap.xml

RSS-лента — API, который выдает вам последние посты или новости с сайта. Было раньше популярно, сейчас все реже, но где-то еще есть! Пример: https://habr.com/ru/rss/hubs/all/

Поищите XHR запросы в консоли разработчика

Все современные вебсайты (но не в дарк вебе, лол) используют Javascript, чтобы догружать данные с бекенда. Это позволяет сайтам открываться плавно и скачивать контент постепенно после получения структуры страницы (HTML, скелетон страницы).

Обычно, эти данные запрашиваются джаваскриптом через простые GET/POST запросы. А значит, можно подсмотреть эти запросы, их параметры и заголовки — а потом повторить их у себя в коде! Это делается через консоль разработчика вашего браузера (developer tools).

В итоге, даже не имея официального API, можно воспользоваться красивым и удобным закрытым API. ☺️

Даже если фронт поменяется полностью, этот API с большой вероятностью будет работать. Да, добавятся новые поля, да, возможно, некоторые данные уберут из выдачи. Но структура ответа останется, а значит, ваш парсер почти не изменится.

Алгорим действий такой:

Открывайте вебстраницу, которую хотите спарсить

Правой кнопкой -> Inspect (или открыть dev tools как на скрине выше)

Открывайте вкладку Network и кликайте на фильтр XHR запросов

Обновляйте страницу, чтобы в логах стали появляться запросы

Найдите запрос, который запрашивает данные, которые вам нужны

Копируйте запрос как cURL и переносите его в свой язык программирования для дальнейшей автоматизации.

Кнопка, которую я искал месяцы

Вы заметите, что иногда эти XHR запросы включают в себя огромные строки — токены, куки, сессии, которые генерируются фронтендом или бекендом. Не тратьте время на ревёрс фронта, чтобы научить свой парсер генерировать их тоже.

Вместо этого попробуйте просто скопипастить и захардкодить их в своем парсере: очень часто эти строчки валидны 7-30 дней, что может быть окей для ваших задач, а иногда и вообще несколько лет. Или поищите другие XHR запросы, в ответе которых бекенд присылает эти строчки на фронт (обычно это происходит в момент логина на сайт). Если не получилось и без куки/сессий никак, — советую переходить на автоматизацию браузера (Selenium, Puppeteer, Splash — Headless browsers) — об этом ниже.

Поищите JSON в HTML коде страницы

Как было удобно с XHR запросами, да? Ощущение, что ты используешь официальное API. 🤗 Приходит много данных, ты все сохраняешь в базу. Ты счастлив. Ты бог парсинга.

Но тут надо парсить другой сайт, а там нет нужных GET/POST запросов! Ну вот нет и все. И ты думаешь: неужели расчехлять XPath/CSS-selectors? 🙅‍♀️ Нет! 🙅‍♂️

Чтобы страница хорошо проиндексировалась поисковиками, необходимо, чтобы в HTML коде уже содержалась вся полезная информация: поисковики не рендерят Javascript, довольствуясь только HTML. А значит, где-то в коде должны быть все данные.

Современные SSR-движки (server-side-rendering) оставляют внизу страницы JSON со всеми данные, добавленный бекендом при генерации страницы. Стоп, это же и есть ответ API, который нам нужен! 😱😱😱

Вот несколько примеров, где такой клад может быть зарыт (не баньте, плиз):

Красивый JSON на главной странице Habr.com. Почти официальный API! Надеюсь, меня не забанят. И наш любимый (у парсеров) Linkedin!

Алгоритм действий такой:

В dev tools берете самый первый запрос, где браузер запрашивает HTML страницу (не код текущий уже отрендеренной страницы, а именно ответ GET запроса).

Внизу ищите длинную длинную строчку с данными.

Если нашли — повторяете у себя в парсере этот GET запрос страницы (без рендеринга headless браузерами). Просто requests.get .

Вырезаете JSON из HTML любыми костылямии (я использую html.find(«=<") ).

Отрендерите JS через Headless Browsers

Если XHR запросы требуют актуальных tokens, sessions, cookies. Если вы нарываетесь на защиту Cloudflare. Если вам обязательно нужно логиниться на сайте. Если вы просто решили рендерить все, что движется загружается, чтобы минимизировать вероятность бана. Во всех случаях — добро пожаловать в мир автоматизации браузеров!

Если коротко, то есть инструменты, которые позволяют управлять браузером: открывать страницы, вводить текст, скроллить, кликать. Конечно же, это все было сделано для того, чтобы автоматизировать тесты веб интерфейса. I’m something of a web QA myself.

После того, как вы открыли страницу, чуть подождали (пока JS сделает все свои 100500 запросов), можно смотреть на HTML страницу опять и поискать там тот заветный JSON со всеми данными.

Selenoid — open-source remote Selenium cluster

Для масштабируемости и простоты, я советую использовать удалённые браузерные кластеры (remote Selenium grid).

Недавно я нашел офигенный опенсорсный микросервис Selenoid, который по факту позволяет вам запускать браузеры не у себя на компе, а на удаленном сервере, подключаясь к нему по API. Несмотря на то, что Support team у них состоит из токсичных разработчиков, их микросервис довольно просто развернуть (советую это делать под VPN, так как по умолчанию никакой authentication в сервис не встроено). Я запускаю их сервис через DigitalOcean 1-Click apps: 1 клик — и у вас уже создался сервер, на котором настроен и запущен кластер Headless браузеров, готовых запускать джаваскрипт!

Вот так я подключаюсь к Selenoid из своего кода: по факту нужно просто указать адрес запущенного Selenoid, но я еще зачем-то передаю кучу параметров бразеру, вдруг вы тоже захотите. На выходе этой функции у меня обычный Selenium driver, который я использую также, как если бы я запускал браузер локально (через файлик chromedriver).

Заметьте фложок enableVNC . Верно, вы сможете смотреть видосик с тем, что происходит на удалённом браузере. Всегда приятно наблюдать, как ваш скрипт самостоятельно логинится в Linkedin: он такой молодой, но уже хочет познакомиться с крутыми разработчиками.

Парсите HTML теги

Если случилось чудо и у сайта нет ни официального API, ни вкусных XHR запросов, ни жирного JSON внизу HTML, если рендеринг браузерами вам тоже не помог, то остается последний, самый нудный и неблагодарный метод. Да, это взять и начать парсить HTML разметку страницы. То есть, например, из Cool website достать ссылку. Это можно делать как простыми регулярными выражениями, так и через более умные инструменты (в питоне это BeautifulSoup4 и Scrapy) и фильтры (XPath, CSS-selectors).

Мой единственный совет: постараться минимизировать число фильтров и условий, чтобы меньше переобучаться на текущей структуре HTML страницы, которая может измениться в следующем A/B тесте.

Даниил Охлопков — Data Lead @ Runa Capital

Подписывайтесь на мой Телеграм канал, где я рассказываю свои истории из парсинга и сливаю датасеты.

Надеюсь, что-то из этого было полезно! Я считаю, что в парсинге важно, с чего ты начинаешь. С чего начать — я рассказал, а дальше ваш ход 😉

Источник

Учимся писать парсер сайта своими руками

Сегодня я приведу вам в пример, который возможно понадобиться начинающим парсерам и возможно вы найдете в нем ценную информацию. В комментариях очень хотелось бы увидеть возможные изменения для упрощения задачи, так что всегда рад услышать ваши мнения.
Передо мной стояла задача заполнить интернет магазин товарами в количестве свыше 50 тыс наименований. Оригиналы товаров лежали на сайтах поставщиков.
Особо заморачиваться с кодом и решением я не стал, поэтому сделал все максимально просто и быстро.
Прикрепленные файлы буду выкладывать на проекте моих друзей и партнеров 2file.ru Будьте уверены что все ссылки всегда будут действующими и вы всегда сможете скачать любой файл из данной инструкции. +размер файлов не ограничен, нет времени ожидания и нет рекламмы.

Первым делом я решил скачать полностью сайт себе чтобы в дальнейшем было проще работать с ним.
Для Windows нам потребуется программа wget (КАЧАЕМ)
Распаковываем например на диск С и для удобства переименовываем в wget.
Далее нажимаем пуск-выполнить-cmd и там вводим CD C:\wget\. Далее нам нужно запустить команду wget.exe -c -p -r -l0 -np -N -k -nv АДРЕС САЙТА 2>wget.log. Описание команд -c -p -r -l0 -np -N -k -nv можно подробно почитать ТУТ. Нажимаем enter и начинается скачивание. В папке wget появляется папка с названием сайта, куда сливается сайт. ВНИМАНИЕ, при больших объемах, сайт может скачиваться даже несколько дней.
. Прошло несколько дней
Вот мы и дождались загрузки сайта на наш компьютер. В моем случаи в корне находились страницы с подробным описанием товаров, так что буду следовать отсюда.
Нам понадобится установленный на компьютере сервер apache+php. Для удобства и быстроты настройки можно использовать например xampp, который можно взять бесплатно на ЭТОМ сайте, где так-же приведен процесс инсталяции.

Ок, теперь у нас стоит апач, есть скачанный сайт. Далее для удобства я перенес все скачанные странички в папку xampp для дальнейшей работы с ними. Чтобы не усложнять код, я переименовал все страницы в порядковые номера чтобы получилось 1.html, 2.html… и так далее. Сделать это очень просто. Например через total commender в меню файлы-групповое переименование. Далее в папке с переименованными страницами я создал index.php файл. Теперь начнем разбираться в коде:

(.+?.) #is’, $html, $matches );
foreach ( $matches[1] as $value ) echo $value.’&ltbr>’;
?>

Первой строчкой я указываю на открытие 132.html, в котором будет осуществляться выборка данных.

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

preg_match_all( ‘#(.+?.)#is’, $html, $matches );

Далее осуществляется вывод полученных данных на экран и спуск на строчку вниз br.

Для выдирания нескольких результатов из одной страницы, можно использовать код на подобии:

(.+?.) #is’, $html, $matches );
preg_match_all( ‘# (.+?.) #is’, $html, $matches1 );
preg_match_all( ‘# (.+?.) #is’, $html, $matches2 );

foreach ( $matches[1] as $value ) echo $value.’ ‘;
foreach ( $matches1[1] as $value ) echo $value.’ ‘;
foreach ( $matches2[1] as $value ) echo $value.’&ltbr>’;
?>

Должно получится что-то вроде (значение1, значение2, значение3 &ltbr>)

Теперь немного дополним наш код чтобы прогнать все наши скачанные страницы. Решил сделать с помощью цикла и получилось что-то вроде этого:

(.+?.) #is’, $html, $matches );
preg_match_all( ‘# (.+?.) #is’, $html, $matches1 );
preg_match_all( ‘# (.+?.) #is’, $html, $matches2 );

foreach ( $matches[1] as $value ) echo $value.’ ‘;
foreach ( $matches1[1] as $value ) echo $value.’ ‘;
foreach ( $matches2[1] as $value ) echo $value.’&ltbr>’;

Отлично, теперь мы видим что-то вроде этого:
значение#значение#значение
значение#значение#значение

Для удобства дальнейшей работы я использовал #. Теперь копируем все что получилось, загоняем в excel, нажимаем данные-текст по столбцам и ставим # в качестве разделителя столбцов. Отлично, мы получили таблицу с результатами нашего парсинга. УРА

Дальнейшая работа зависит от вашей фантазии и цели. Спасибо за внимания, надеюсь на инвайт.

Источник

Оцените статью
Своими руками