«Правильный» html парсинг
Первый раз я запустил Eclipse еще весной, почитал книжки на английском, поставил SDK, немного поигрался и забросил. В начале зимы я купил себе первый смартфон на базе Android, но вновь вернутся к разработке меня подтолкнул недавний пост, в котором говорилось, что можно обойтись и знанием C#, с которым в отличии от Java я знаком. Мне было достаточно одного вечера, чтобы понять, что за связку Visual Studio и Monodroid я больше не сяду, позже я прочитал этот пост, где полностью согласился с автором.
После небольшого вступления перейду к теме топика. Довольно большое количество приложений под мобильные устройства взаимодействуют с сайтами и не секрет, что порой нужно получить какую-то информацию со страницы — это может быть курс валют или что-нибудь другое, и нет никакого желания делать это посредством браузера.
Большинство разработчиков, получают html код страницы и перегоняют его в xml, что является неправильным подходом, так как html является «правильным» xml не всегда, вроде на хабре писали, что для браузера не обязателен тег html (современный браузер и без него должен отобразить страницу) или просто будут ошибки, тогда на помощь приходят библиотеки. Из них я выбрал HtmlCleaner.
Под катом я расскажу, как подключить эту библиотеку, а также напишем простой парсер stackoverflow.com.
Рассказывать как установить Android SDK, Eclipse и ADT Plugin я не буду, если эти слова Вам ничего не говорят, то посетите эти две ссылки:
Installing the SDK
ADT Plugin for Eclipse
Главная страница stackoverflow.com выглядит следующим образом:
Парсить я буду информацию, выделенную красными прямоугольниками.
Всё рассчитано на новичков, поэтому будет много картинок. На данном этапе у Вас должен быть полностью настроенный Eclipse, для создания проекта нажимаем File -> New -> Project… и выбираем Android Project, после чего заполним форму:
Пишу для своего устройства, поэтому выбрал версию 2.2, второй важный параметр — это package name, который должен быть уникальным, принято, что это имя сайта наоборот, плюс название приложения. Тесты создавать не будет, поэтому смело нажимаем Finish. Создался проект, рекомендую Вам изучить какие файлы и где лежат, но по своему опыту скажу, что сразу я малость испугался, того количества файлов, которое появилось при первом запуске Eclipse.
Приступим к редактированию файла res\layout\main.xml, тут я удалю TextView и добавлю два элемента управления: Button и ListView, изменю идентификаторы, для кнопки установлю android:layout_width=«fill_parent» и android:text=«Получить данные». Готовый результат выглядит таким образом:
* This source code was highlighted with Source Code Highlighter .
Это простейший интерфейс, в случае, если Вы сделаете приложение и решите опубликовать его в маркете, то обязательно его нужно изменить, поставить тот же фон через android:background=»@drawable/Имя_файла_без_расширения» и т.д.
Для парсинга нам понадобиться скачать библиотеку htmlcleaner-2.2.jar, далее её следует подключить добавив в Build Paths. Хороший мануал как это сделать можно найти тут, если у Вас появились какие-то трудности.
Прежде всего нужно указать, что нашему приложению нужен интернет, иначе у Вас ничего не выйдет, добавим в файл AndroidManifest.xml:
Теперь создадим класс HtmlHelper, который будет делать основную работу:
public class HtmlHelper TagNode rootNode;
//Конструктор
public HtmlHelper(URL htmlPage) throws IOException
//Создаём объект HtmlCleaner
HtmlCleaner cleaner = new HtmlCleaner();
//Загружаем html код сайта
rootNode = cleaner.clean(htmlPage);
>
List getLinksByClass( String CSSClassname)
List linkList = new ArrayList ();
В главном классе установим слушателя для кнопки и вызовем асинхронно парсинг с помощью AsyncTask, сразу я делал с помощью создания потока и потом через handler обновлял интерфейс, но прочитал, что это не лучшее решение и лучше для этих целей подходит AsyncTask, также, чтобы было видно, что приложение работает я вызову диалог, который будет информировать о процессе. Собственно главный класс выглядит следующим образом:
public class StackParser extends Activity /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Находим кнопку
Button button = (Button)findViewById(R.id.parse);
//Регистрируем onClick слушателя
button.setOnClickListener(myListener);
>
//Диалог ожидания
private ProgressDialog pd;
//Слушатель OnClickListener для нашей кнопки
private OnClickListener myListener = new OnClickListener() public void onClick(View v) //Показываем диалог ожидания
pd = ProgressDialog.show(StackParser. this , «Working. » , «request to server» , true , false );
//Запускаем парсинг
new ParseSite().execute( «http://www.stackoverflow.com» );
>
>;
private class ParseSite extends AsyncTask< String , Void, List < String >> //Фоновая операция
protected List < String >doInBackground( String . arg) List < String >output = new ArrayList < String >();
try
HtmlHelper hh = new HtmlHelper( new URL(arg[0]));
List links = hh.getLinksByClass( «question-hyperlink» );
for (Iterator iterator = links.iterator(); iterator.hasNext();)
TagNode divElement = (TagNode) iterator.next();
output.add(divElement.getText().toString());
>
>
catch (Exception e)
e.printStackTrace();
>
return output;
>
//Событие по окончанию парсинга
protected void onPostExecute( List < String >output) //Убираем диалог загрузки
pd.dismiss();
//Находим ListView
ListView listview = (ListView) findViewById(R.id.listViewData);
//Загружаем в него результат работы doInBackground
listview.setAdapter( new ArrayAdapter< String >(StackParser. this ,
android.R.layout.simple_list_item_1 , output));
>
>
>
Если Вы всё делали со мной, то у Вас должна была получится, следующая иерархия файлов:
А после запуска приложение должно выглядеть следующим образом:
Ссылка на скачивание: приложение
Вывод
Мы узнали, что есть довольно много библиотек для парсинга, познакомились с одной из них, написали приложение, которое в фоне парсит сайт и при готовности показывает нам результат своей работы. В принципе, его можно развить и дальше, после чего не исключено, что оно станет популярным в определенных кругах, первое, что приходит в голову — это при клике на вопрос, открывать данный вопрос в новом окне через WebView.
Парсер
Парсер — это программа для сбора и систематизации информации, размещенной на различных сайтах. Источником данных может служить текстовое наполнение, HTML-код сайта, заголовки, пункты меню, базы данных и другие элементы. Процесс сбора информации называется парсинг (parsing).
«IT-специалист с нуля» наш лучший курс для старта в IT
Парсеры используются в интернет-маркетинге для сбора информации с сайтов-конкурентов, а также для анализа собственных веб-ресурсов. Они позволяют обрабатывать большие массивы данных в автоматическом режиме. Это ускоряет и упрощает проведение маркетинговых исследований.
Профессия / 8 месяцев
IT-специалист с нуля
Попробуйте 9 профессий за 2 месяца и выберите подходящую вам
Как работает парсер
Термин «парсинг» произошел от английского глагола to parse, означающего в переводе с английского «по частям». Процесс представляет собой синтаксический анализ любого набора связанных друг с другом данных. В общем виде парсинг выполняется в несколько этапов:
- Сканирование исходного массива информации (HTML-кода, текста, базы данных и т.д.).
- Вычленение семантически значимых единиц по заданным параметрам — например заголовков, ссылок, абзацев, выделенных жирным шрифтом фрагментов, пунктов меню.
- Конвертация полученных данных в формат, удобный для изучения, а также их систематизация в виде таблиц или отчетов для дальнейшего использования.
Объектом парсинга может быть любая грамматически структурированная система: информация, закодированная естественным языком, языком программирования, математическими выражениями и т.д. Например, если исходный массив данных представляет собой HTML-страницу, парсер может вычленить из кода информацию и перевести ее в текст, понятный для человека. Или конвертировать в JSON — формат для приложений и скриптов.
Читайте также Востребованные IT-профессии 2023 года: на кого учиться онлайн
Доступ парсера к сайту возможен:
- через протоколы HTTP, HTTPS или веб-браузер;
- с использованием бота, имеющего права администратора.
Получение данных парсером — семантический анализ исходного массива информации. Программа разбивает его на отдельные части (лексемы): слова, словосочетания и т.д. Парсер проводит их грамматический анализ, преобразуя линейную структуру текста в древовидную (синтаксическое дерево). Такая форма упрощает «понимание» информационного массива компьютерной программой и бывает двух типов:
- дерево зависимостей — такая структура состоит из компонентов, находящихся в иерархических отношениях друг к другу;
- дерево составляющих — в структуре этого типа компоненты находятся в тесной зависимости друг с другом, но без иерархических отношений.
Также результат работы парсера может представлять собой сочетание моделей. Программа действует по одному из двух алгоритмов:
- Нисходящий парсинг. Анализ осуществляется от общего к частному, а синтаксическое дерево разрастается вниз.
- Восходящий парсинг. Анализ и построение синтаксического дерева осуществляются снизу вверх.
Выбор конкретного метода парсинга зависит от конечной цели. В любом случае, парсер должен уметь вычленять из общего массива только необходимые данные, а также преобразовывать их в удобный для решения задачи формат.
Станьте веб-разработчиком и найдите стабильную работу на удаленке
Преимущества и недостатки парсеров
Применение программ-парсеров позволяет:
- автоматизировать процесс анализа и снижать нагрузку на сотрудников, перенаправлять их время и силы на решение других задач;
- ускорять анализ большого объема информации — например, нескольких сотен страниц интернет-магазина или обширную базу данных;
- выявлять ошибки на сайте или в любом другом информационном продукте, если в программе заданы настройки на их поиск.
К недостаткам парсеров можно отнести не всегда релевантный анализ данных. Однако в большинстве случаев это зависит от возможностей программы, качества ее настройки пользователем. В большинстве случаев информация, выдаваемая парсером, требует незначительной обработки для дальнейшего использования.
Применение парсеров
Парсинг применяется в любых областях, где требуется проанализировать и систематизировать большой объем данных:
- В программировании. Компьютер может воспринимать и «понимать» только машинный код — набор нулей и единиц. Чтобы заставить машину выполнить какую-либо операцию, человек использует языки программирования, которые непонятны компьютеру. Поэтому специальное приложение сначала проводит парсинг написанной пользователем программы и переводит полученные данные в бинарный машинный код.
- В создании сайтов. Как и языки программирования, языки разметки (например HTML) непонятны компьютеру. Чтобы он смог отобразить HTML-разметку в виде визуально структурированного и понятного интерфейса сайта, парсер браузера анализирует исходный код страницы, вычленяет нужные данные, переводит их в понятный машине формат. Также парсинг позволяет выявить ошибки и недочеты в созданном сайте.
- Веб-краулинг. Это частный случай парсинга. Робот-парсер поисковика в ответ на запрос пользователя просматривает релевантные ему сайты, после чего выбирает наиболее подходящую по содержанию страницу. Особенность краулеров в том, что они не извлекают данные со страниц, как другие парсеры, а ищут в них совпадения с запросом пользователя.
- Агрегация новостей. Для упорядоченной подачи новостей сайты-агрегаторы или новостные агентства используют парсеры. Они собирают обновления со всех доступных источников, анализируют их и подают сотрудникам для конечной редактуры и публикации.
- Интернет-маркетинг. В SEO и SMM с помощью парсеров собираются и анализируются данные пользователей, товарные позиции в интернет-магазинах, метатеги (заголовки, title и description), ключевые слова и другая информация. Эти данные используются для оптимизации сайта, продвижения коммерческих групп в социальных сетях, настройки таргетированной и контекстной рекламы. Проверка размещенного на веб-ресурсе текста на плагиат также является разновидностью парсинга.
- Мониторинг цен. Парсерами можно извлечь расценки товаров на сайтах-конкурентах, чтобы проанализировать текущую ситуацию на рынке и выработать ценовую политику. Также с их помощью можно привести прайс-листы на собственном сайте в соответствие с ценами у поставщиков.
Программы-парсеры
В веб-разработке и продвижении используется большое количество бесплатных и платных программ для парсинга сайтов. К числу самых популярных относятся:
- Screaming Frog SEO Spider. Это британская программа для комплексного анализа сайтов со множеством полезных опций. Она осуществляет поиск битых ссылок, входящих и исходящих ссылок, выявляет дубли метатегов и заголовков, ключевые слова, отдельные URL и т.д. Среди полезных дополнительных опций — генерация sitemap, сканирование сайтов, требующих оптимизации, проверка файла robots.txt. Программа имеет бесплатную версию, но функционал ограничен базовыми возможностями.
- ComparseR. Это приложение также позволяет парсить сайты, но у нее отсутствует функция поиска внутренних и внешних ссылок. В остальном оно не уступает Screaming Frog по возможностям, хотя имеются ограничения по производительности при анализе крупных сайтов — например, интернет-магазинов или больших информационных порталов. Дополнительным преимуществом является более удобный интерфейс, упрощающий освоение программы и ее использование.
- Netpeak Spider. Одно из самых популярных приложений для парсинга, ориентированное на работу с крупными сайтами (с миллионом и более страниц). Среди преимуществ — наличие всего набора инструментов для анализа и продвижения веб-ресурсов разного типа, настраиваемые фильтры параметров, дополнительные опции наподобие генерации HTML-карты сайта, поиска ссылок nofollow, выгрузки отчетов и т.д. Единственный недостаток — полный функционал доступен по подписке, которую нужно регулярно продлевать.
- Xenu Link Sleuth. Бесплатный парсер, предназначенный для поиска битых ссылок и других ошибок на сайте. Xenu нельзя использовать для комплексного и подробного анализа веб-ресурсов. Также есть проблемы с производительностью, но с учетом доступности недостатки приемлемы.
Можно ли использовать парсеры
Распространено мнение, что парсинг сайтов как минимум неэтичен, а в некоторых случаях и незаконен. Действительно, парсеры собирают информацию с чужих веб-ресурсов, баз данных и других источников. Однако в большинстве случаев сведения находятся в открытом доступе, то есть использование программ не нарушает закон. Противозаконным может стать применение данных, например:
- для спам-рассылки и звонков. Это нарушает закон о защите персональных данных;
- копирование и использование информации с сайта-конкурента на собственном ресурсе. Это может нарушать авторские права.
В целом, парсинг не нарушает нормы законодательства и этики. Автоматизированный сбор информации позволяет сделать сайт и реализуемый с его помощью продукт более удобным для клиентов.
Веб-разработчик с нуля
Веб-разработчик — мастер на все руки. Он создает программы и приложения для любых сфер и компаний: от небольшой кофейни до международных банков. Станьте специалистом, который создает востребованный продукт
Статьи по теме:
Парсинг страниц сайтов(html-контента) на php.
Заметка посвящается парсингу, в частности парсинг сайтов, парсинг страниц, парсинг в веб-среде, парсинг html-контента сайта. В процессе разработки различных веб-сервисов очень часто приходится сталкиваться с задачами, в которых требуется быстро получить различного рода информацию в больших объемах. В основном это связано с граббингом, кражей информации, как хотите это называйте. Дело в том, что информация доступна и открыта. Особенность парсинга — это быстрый и автоматизированный сбор данных, контента со страниц сайта. Сейчас очень популярно парсить в веб-среде, а именно парсить сайта, который содержать хоть какую-нибудь ценность и актуальность для людей. Особой ценностью является каталог товаров, включая картинки, базы данных справочников и многое другое, что может пригодиться для конкурентов. Давайте попробуем спарсить нужную информацию в html, попробуем достать все ссылки с нескольких страниц нашего сайта. Для начала нам необходимо получить контент сайта в формате html. Для этого нам достаточно знать адреса нужных страниц. Хочу показать 2 основных способа получения контента со страницы сайта: В первую очередь приготовим массив с нужными адресами страниц:
//3 ссылки нашего сайта: $urls = array('http://hello-site.ru/blog/','http://hello-site.ru/web-notes/','http://hello-site.ru/games/');
1 вариант — php функция file_get_contents. Функция возвращает html-строку, которую мы будем парсить на ссылки:
//помещаем каждую ссылку в функцию file_get_contents foreach($urls as $urlsItem) < $out .= file_get_contents($urlsItem); //и добавляем содержание каждой страницы в строку >echo $out; //здесь контент всех трех страниц
2 вариант — CURL. Библиотека, которая поддерживается php и имеет большой набор настроек, от POST-запросов до работы с FTP. Рассмотрим стандартный вызов библиотеки curl, который отдаст нам контент сайта:
foreach($urls as $urlsItem) < //пропускаем каждую ссылку в цикле $output = curl_init(); //подключаем курл curl_setopt($output, CURLOPT_URL, $urlsItem); //отправляем адрес страницы curl_setopt($output, CURLOPT_RETURNTRANSFER, 1); curl_setopt($output, CURLOPT_HEADER, 0); $out .= curl_exec($output); //помещаем html-контент в строку curl_close($output); //закрываем подключение >echo $out; //здесь контент всех трех страниц
Теперь в нашей строке $out находится контент всех трех страниц. Итак, переходим непосредственно к парсингу нашей строки. Опять же хочу показать 3 варианта решения нашей задачи: «нативный» способ на php, с помощью встроенной библиотеки DOMDocument и библиотеки SimpleHTMLDOM. 1. php функция explode. Функция находит искомый символ или часть строки и делит целую строку на элементы массива. Повторюсь, нам необходимо получить значения всех атрибутов href у тегов a, для этого будем делить общую строку на некоторые части\отрезки:
// explode $hrefs = explode(' foreach($hrefText as $hrefTextItem) < //избавляемся от ссылок с пустым атрибутом href if($hrefTextItem!='')< $clearHrefs[]=$hrefTextItem; >> $clearHrefs = array_unique($clearHrefs); //избавляемся от одинаковых ссылок print_r($clearHrefs); // в итоге у нас массив со всем ссылками с 3х страниц
Если распечатать наш массив, будет примерно следующее:
Array ( [0] => / [1] => /hello [3] => /timer/ [4] => /leftmenu/ [5] => /faq/ [6] => /blog/ [8] => /web-notes/ [9] => /ordersite/ [10] => /games )
2. встроенная библиотека DOMDocument. Работаем с классом примерно следующим образом:
//domelement $dom = new DOMDocument; //создаем объект $dom->loadHTML($out); //загружаем контент $node = $dom->getElementsByTagName('a'); //берем все теги a for ($i = 0; $i < $node->length; $i++) < $hrefText[] = $node->item($i)->getAttribute('href'); //вытаскиваем из тега атрибут href > foreach($hrefText as $hrefTextItem) < //избавляемся от ссылок с пустым атрибутом href if($hrefTextItem!='')< $clearHrefs[]=$hrefTextItem; >> $clearHrefs = array_unique($clearHrefs); //избавляемся от одинаковых ссылок print_r($clearHrefs); // в итоге у нас массив со всем ссылками с 3х страниц
Результат такого кода ровно такой же, что и с помощью функции explode. 3. библиотека SimpleHTMLDOM. Ее необходимо подключать из файла. Работа примерно схожа с DOMDocument. Работаем с классом:
//simplehtml include('simple_html_dom.php'); //подключаем файл с классом SimpleHTMLDOM $html = new simple_html_dom(); //создаем объект $html->load($out); //помещаем наш контент $collection = $html->find('a'); //собираем все теги a foreach($collection as $collectionItem) < $articles[] = $collectionItem->attr; //массив всех атрибутов, href в том числе > foreach($articles as $articlesItem) < $hrefText[] = $articlesItem['href']; //собираем в массив значения подмассива с ключом href >foreach($hrefText as $hrefTextItem) < //избавляемся от ссылок с пустым атрибутом href if($hrefTextItem!='')< $clearHrefs[]=$hrefTextItem; >> $clearHrefs = array_unique($clearHrefs); //избавляемся от одинаковых ссылок print_r($clearHrefs); // в итоге у нас массив со всем ссылками с 3х страниц
Повторюсь, результат в массив ровно такой же как и выше в двух вышеперечисленных. Теперь, имея массив со всеми ссылками, собранными с трех страниц сайта, можно отправить ссылки в нужное русло, все зависит от задачи и фантазии. Имея такие возможности, можно спарсить большое количество данных самого разного вида информации, картинки, тексты, логи и т.д. Чужая информация в ваших руках, распоряжайтесь как вам угодно, но сами защищайтесь, хотя это невозможно) Успехов!
Как спарсить любой сайт?
Меня зовут Даниил Охлопков, и я расскажу про свой подход к написанию скриптов, извлекающих данные из интернета: с чего начать, куда смотреть и что использовать.
Написав тонну парсеров, я придумал алгоритм действий, который не только минимизирует затраченное время на разработку, но и увеличивает их живучесть, робастность, масштабируемость.
TL;DR
Чтобы спарсить данные с вебсайта, пробуйте подходы именно в таком порядке:
- Найдите официальное API,
- Найдите XHR запросы в консоли разработчика вашего браузера,
- Найдите сырые 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, который нам нужен!
Вот несколько примеров, где такой клад может быть зарыт (не баньте, плиз):
Алгоритм действий такой:
- В 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 со всеми данными.
driver.get(url_to_open) html = driver.page_source
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).
def get_selenoid_driver( enable_vnc=False, browser_name="firefox" ): capabilities = < "browserName": browser_name, "version": "", "enableVNC": enable_vnc, "enableVideo": False, "screenResolution": "1280x1024x24", "sessionTimeout": "3m", # Someone used these params too, let's have them as well "goog:chromeOptions": , "prefs": < "credentials_enable_service": False, "profile.password_manager_enabled": False >, > driver = webdriver.Remote( command_executor=SELENOID_URL, desired_capabilities=capabilities, ) driver.implicitly_wait(10) # wait for the page load no matter what if enable_vnc: print(f"You can view VNC here: ") return driver
Заметьте фложок enableVNC . Верно, вы сможете смотреть видосик с тем, что происходит на удалённом браузере. Всегда приятно наблюдать, как ваш скрипт самостоятельно логинится в Linkedin: он такой молодой, но уже хочет познакомиться с крутыми разработчиками.
Парсите HTML теги
Мой единственный совет: постараться минимизировать число фильтров и условий, чтобы меньше переобучаться на текущей структуре HTML страницы, которая может измениться в следующем A/B тесте.
Даниил Охлопков — Data Lead @ Runa Capital
Подписывайтесь на мой Телеграм канал, где я рассказываю свои истории из парсинга и сливаю датасеты.
Надеюсь, что-то из этого было полезно! Я считаю, что в парсинге важно, с чего ты начинаешь. С чего начать — я рассказал, а дальше ваш ход