astur
0

Требования к системе… по большому счёту как у jsdom, остальное там по мелочи.


Javascript выполняет. Через evaluate.


Смотря что понимать под "постоянно работающим парсером". Всё, в конечном итоге, сводится к требуемой частоте запросов. Если частота небольшая — можно использовать, если большая — нельзя (как и любой другой hedless). Лично я любые hedless использую только для разовой инициализации сессии, а дальше — честные http-запросы. Обратите внимание, что в этой статье рассматривается только задача получения cookies при запуске скрейпера. Предполагается, что дальше можно будет скрейпить как обычно.

astur
0

Честно говоря, лучшая инфа, что мне попадалась по этой теме — это те две ссылки, которые kirill3333 привёл в комментариях к этой статье (выше и ниже соответственно). Главное, что стоит знать, на мой взгляд, если разработчик сайта захочет детектировать робота — значит он детектирует и гарантированных способов ему помешать нет. Просто как пример того, насколько далеко можно зайти в этом направлении посмотрите технологии на сайте areyouahuman.com. И это ещё не предел.

astur
0

Ну, htmlunit — это обычный headless. Как PhantomJS только на Java. Защититься от него можно так же легко/трудно, как от PhantomJS. Вот тут я эту тему немного раскрыл, если что.

astur
0

Встречу. Но это не одно и то же.


Парсинг — это преобразование строки в удобные для программы данные, а веб-скрейпинг — это вытаскивание данных со страниц. Ну, это если грубо.


В первой статье цикла я вроде бы показал как соотносятся парсинг со скрейпингом.


На импортных биржах "parsing" — это когда, например, есть здоровенный файл (или куча файлов) в экзотическом формате и надо из него надёргать данные. А "scraping" там — это когда есть сайт, с которого надо вытащить данные, тем или иным способом, хоть скриптом, хоть копипейстом.


Короче, я понял, проблема есть. Постараюсь сделать статью с терминологией по всей этой области.

astur
0

В боевых условиях я использую phantomjs только на этапе авторизации, чтобы получить куки, сохранить их и использовать пока не устареют. Я делал скрейпинг адресов ревьюеров из топа. Надо было сделать 10000 запросов. Даже через needle это долго, а уж через hedless — тем более. Добавлял в каждый запрос куки, которые в самом начале были получены из phantomjs, а сами запросы делал с помощью needle. Все 10000 прошли без сбоев с одним набором кук. А вот на этапе тестирования авторизации капча вываливалась после десятка-другого запросов.


В принципе, так и должно быть. 10000 авторизованных запросов для Amazon — ерунда, а вот подозрительная активность при авторизации — это может быть подготовка скрейпинга, а может быть и взлом денежного аккаунта.

astur
0

Да, когда есть возможность — лучше использовать готовый API, чем страницы скрейпить. Поддерживаю.
Капчи я наблюдал после 10 успешных входов подряд. Через некоторое время опять начинал пускать без капчи. После авторизации с готовыми куками мне капча вообще не попадалась.
Прокси при авторизации тем же аккаунтом, естественно, не помогают, ибо и так понятно, что это тот же юзер :)
Mink — это неплохая штука. Я его не упомянул просто потому что подбирал варианты для Node, а так — да.

astur
+1
Лучше использовать ORM.

Ну, это уже будет не только ради читаемости :)


Тут можно использовать ORM, да. Но "лучше" — это немного субъективно. Я стараюсь держаться подальше от холивара "ORM vs. raw SQL".


и что это за слово такое «скрейпинг»?

Это слово, которым скрейперы иногда называют скрейпинг :)


Хочется сказать, что "так исторически сложилось", но, на самом деле общепринятого устоявшегося русскоязычного термина для этого понятия пока нет, и скрейпинг иногда как только не называют. Это точно не просто "получение" или "извлекание", а вполне конкретная разновидность получения или извлекания. Термин "scraping" в английском изначально был жаргонным, но прижился (он означает выскребание данных из источников, явно для этого не предназначенных). Может и "скрейпинг" в русском приживётся, но не факт. Пока в сети большая часть общения о скрейпинге идёт на английском, так что проще использовать английский устоявшийся термин (как в случае с "браузером"), а не тратить время на внедрение "правильного" русскоязычного термина.


Если руки дойдут — сделаю статью по терминологии в этой области.

astur
0

Вот таким вот образом.


Или вот таким ещё.


Обе ссылки из комментария к первой статье.

astur
0
Он JVM не ставит.
astur
0
Ну, python, всё-таки, почти на два десятилетия старше. Будет и под Node.js изобилие готового кода.
astur
0
Да, всё верно. Оба решения требуют установки Selenium+JVM. Насколько я понимаю, отдельного npm-пакета, содержащего рабочий Selenium, не существует. Технически было бы правильнее портировать Selenium (и драйверы браузеров) на js, но такого, вроде бы, тоже пока нет.
astur
0
Обычно клиент заказывает доработку парсера под эти изменения. Это обычный риск и большинство клиентов это понимают. Некоторые сразу оговаривают условия «сопровождения» скрипта.

Вообще, если только структура html поменялась, то это пустяковая проблема, она быстро решается. Вот если сама архитектура бэкенда меняется или защита усиливается — тогда это практически новый заказ. Это большинство клиентов как минимум способны понять, если их заранее предупредить.
astur
0

В предыдущем комменте пункты 2,3,4, конечно же. Чёртова разметка :)

astur
0
  1. "Сложнее" тут стоит трактовать как "Дороже для заказчика". Кто-то откажется, кто-то заплатит за дополнительную возню.
  2. Ну, вы преувеличиваете. Далеко "не в любом случае". Пожалуй, это тема для отдельной статьи.
  3. О, да! :)
astur
0
  1. Текст таблички заполняют джаваскриптом не просто так, а из какого-то источника. На самом деле не важно как данные отображаются на сайте, важно в каком виде они приходят. Например, джаваскрипт может брать данные для таблицы из XML или JSON запрошенного по Ajax. Ну, или из массива в самом джаваскрипте. Это относительно простые случаи. Бывает и так, что данные приходят в зашифрованном виде. Или передаются по WS. Или ещё как-то по-сложному. Тут уж приходится думать, стоят ли эти данные такой возни.
  2. Капча ломается специальными сервисами. Они платные и не сто процентов угадывают, но они есть. Скрейпинг защищённого капчей сайта — типичный заказ на биржах фриланса.
  3. Адская защита — повод задуматься о легальности скрейпинга именно этого сайта. Но ломается любая защита. Без исключений. Как минимум реверс-инжинирингом скриптов сайта. Бывает так, что скрейпер, специализирующийся на таких сайтах, работает в команде с хакером.
  4. Один из самых действенных способов обхода защиты — написать владельцам сайта и попросить доступ к API или прямо готовые данные. Не всегда помогает, но чаще, чем можно предположить. А уж если не стесняться заплатить, то часто получается дешевле, чем нанимать хакера.
astur
0

Тут принцип простой: если скрипт на странице может распарсить ответ, пришедший на Ajax-запрос, то в принципе его распарсить можно. Если не DOM-парсером или XPath, так уж регулярками точно. Но иногда приходится подумать, да. Таблицы без классов и ID – это не так уж и сложно по сравнению с тем, что иногда встречается.


Я не останавливаюсь на теме парсинга слишком подробно только потому, что именно этот аспект скрейпинга описан очень подробно во множестве статей по всему вебу. От условного "парсинга для чайников" и до условного "вуду-магия профессионального парсинга". Остальные аспекты скрейпинга описаны далеко не так хорошо. Некоторые начинающие скрейперы даже не знают о существовании других аспектов. Иногда даже называют скрейпинг парсингом. Я стараюсь подобрать примеры с простым парсингом, чтобы сделать акцент на остальных моментах. Конечно, в реальной жизни попадаются сайты, которые парсить очень непросто, тут не поспоришь.

astur
0

horseman – это просто способ запускать PhantomJS из ноды.


PhantomJS, как и все остальные headless-браузеры, отличается от Scrapy тем, что не просто читает/парсит http-ответы и формирует http-запросы, а выполняет скрипты с сайта. Другой принцип. Свои плюсы, свои минусы.

astur
0

Совсем подобного нет, насколько я знаю. Платформа ещё молодая, а такие фреймворки быстро не делаются. Можно, конечно, написать скрейпер в стиле Python, не использующий сильные стороны Node.js, но он будет хуже Scrapy. Пока есть несколько сырых проектов, которые рано массово рекомендовать. Одно время подавал надежды node-crawler, но его поддержка прекращена, а замены, которые его автор рекомендует, мягко говоря не очень хороши.


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


Ещё есть такой момент, что с каждым годом писать фреймворки для скрейпинга становится всё труднее. Появляется всё больше частных случаев, которые надо учитывать, причём одновременно. И требования у заказчиков всё экзотичнее. Может быть напишу ещё об этом всём поподробнее.

astur
0

Да, хорошая штука. Для node.js нечто подобное только ещё предстоит написать.


Суть в том, что подобные фреймворки появляются только тогда, когда реальный практик берётся изучать и использовать самые основы, а не выбирает из имеющихся недорешений и костылей к ним. Я на 100% уверен, что lorien умеет скрейпить без фреймворка, просто для него это пройденный этап.

astur
+1

Да, их много. Для Node.js ещё вот эти есть:


astur
0
Ну… скрипт на perl или несколько скриптов на perl соединённые через bash — тут слишком тонкая грань. Но по сути я с вами согласен, парсинг нескольких незащищённых страниц — это пустячная задача.
astur
0
В большинстве таких случаев данные не генерятся, а запрашиваются по ajax или как-то ещё, но в открытом виде. Или генерятся каким-то очевидным образом. Если данные трудно получить без таких вещей как PhantomJS, то владелец сайта точно против того, чтобы его скрейпили. И стоит задуматься, что у него могут быть не только хорошие хакеры, но и хорошие юристы. В любом случае, весь код страницы открыт для реверс-инжиниринга, вопрос только в трудоёмкости.
astur
+2
Я пока не готов написать обзор инструментов для скрейпинга, но среди них много неплохих решений для рутинных задач. Проблема в том, что существуют не только рутинные задачи. Более того, существуют задачи, про которые далеко не сразу можно понять рутинные они или нет.

Защита пишется влёгкую. Конечно, это типичная «битва брони и снаряда», и пока одни люди совершенствуют защиты — другие люди совершенствуют методы их обхода. Анализ заголовков браузера — это в последние годы и защитой-то не считается. Сейчас сайт определит, что вы зашли не из браузера, так как в ваших http-запросах не будет тех хитрых зашифрованных данных, которые в браузере вычислились бы подключённым js-скриптом, крайне трудным для реверс-инжиниринга. В запрос можно подставить всё — куки, заголовки, данные форм и так далее — однако все эти данные откуда-то нужно получить, а они не обязательно хранятся в http-ответах в открытом виде. Есть и другие способы защиты, вплоть до анализа частоты запросов. Это серьёзно. Чтобы понять, насколько это серьёзно, надо осознать, что большая часть защит пишется не от скрейперов, а от профессиональных взломщиков банковских онлайн-клиентов, а уж потом используется и против скрейперов тоже.
astur
+1
Я бы даже сказал, что задача древняя как Netscape. Но веб развивается, появляются сложности, которых раньше не было. Я занимался скрейпингом ещё до IE8 и берусь утверждать, что скрейпинг «уже не торт».

Тема выбора языка для скрейпинга тянет на отдельную статью. Для проверки баланса и других подобных задач bash более чем достаточно. Тут я согласен. Но если нужно пройтись по десятку другому тысяч ссылок — тут уже стоит использовать… ну, хотя бы perl :)

Смысл статьи в том, чтобы на простом примере показать те основы, которые нужно хорошо знать, чтобы поверх них проектировать решения сложных задач. Естественно я планирую развивать тему.
astur
0
Знакомо :)
astur
0
Есть довольно много подобных готовых инструментов. Проблема в том, что они подходят только основные задачи.

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

Я и сам использую универсальный модуль собственного сочинения и написание скрейпера для простого сайта у меня занимает от получаса, но бывают случаи, когда приходится вспоминать знания низкоуровневых основ. Это происходит всё реже, так как модуль непрерывно совершенствуется после таких случаев, но это всегда будет происходить, так как веб — это очень терпимая к нарушениям и ошибкам среда, где универсальные решения крайне сложно делать. Это я ещё не говорю о том, что даже начинающий хакер легко напишет защиту от сервисов уровня screen-scraper.com.
astur
+1
— needle отправляет некий минимальный набор заголовков. Без этого никак, да.

— Я имел в виду, что если html достаточно «семантический» для того, чтобы использовать CSS-селекторы в jQuery, то эти же селекторы можно использовать и в cheerio. И то и другое — DOM-парсер в своей основе, так что если на странице используют jQuery, то она под него оптимизирована и cheerio на ней будет хорошо работать. Просто иногда бывает жуткая мешанина из div вообще без атрибутов и сориентироваться можно только по текстовым данным — тогда любые DOM-парсеры справляются плохо (а иногда и регулярки подводят).
astur
+1
Как минимум, NW хорош, когда заказчик просит не гиковский скрипт для возни с шеллом, а обычную программу для простых людей.
astur
+1
Да, бывают сайты, где только Selenium, только хардкор. К счастью, их мало :)

Борются часто не со скрейпингом, а, например, с ботами-коментаторами, с накруткой, с DDoSами, с попытками взлома и так далее, а скрейпинг попадает под раздачу. Но иногда такая хитрая защита означает настойчивую просьбу не скрейпить, и тогда это уже вопрос морали и закона. Но технически через Selenium скрейпится всё, что можно скрейпить вручную.
astur
0
Ух ты! В 2001 году это был тот ещё экстрим.

С терминологией в этой области до сих пор бардак. Возможно решусь сделать словарик отдельной статьёй. Пока в поисковике приходится десятки терминов пробивать, чтобы ничего не упустить. Термин «Web scraping» более-менее устоялся на англоязычных биржах фриланса.
astur
+1
Статьи хорошие, да )

1. Никто не мешает собрать несколько модулей в один и использовать его и для всей последовательности задач. Проблема в том, что универсальные модули часто не учитывают много частных случаев, так что постоянно приходится лезть под капот, поэтому стоит иметь представление о том, как там всё устроено. Я и сам использую для скрейпинга собственный модуль, который «берёт на себя и HTTP, и парсинг DOM, и разрешение ссылок, и правильную обработку кодировок» и много чего ещё делает, но часто попадаются сайты, которые он не в состоянии обработать. Приходится к дедлайну всё делать на коленке из специализированных модулей, а потом, в спокойной остановке, допиливать универсальный модуль на будущее. Так он и развивается.

2. Всё верно. Вообще, это отдельная тема, и по ней я тоже планирую отписаться. Просто для начала взял пример попроще, где и без этого можно справиться, чтобы статья в здоровенный учебник не превращалась :)

3. Упорядочить можно уже готовые данные. Надо просто предусмотреть соответствующие поля заранее. Огромные структуры скрейпить в память — сизифов труд, да. В идеальном мире стоит писать в БД и проверять ошибки при перезапусках. Но в реальном мире заказчики иногда просят сохранение в читабельные файлы (например, им лень или трудно поднять БД на своей стороне), так что приходится выкручиваться, и не только с сортировкой. Про скрейпинг больших объёмов тоже будет статья, да.

4. Всякое бывает. Некоторые сайты честно просят не пинать их ботами чаще, чем раз в Х секунд, например. Теоретически, можно скрейпить параллельно через несколько прокси, и блокировки не будет, но можно, например, положить сервер нагрузкой, что как минимум не этично. Надо смотреть по ситуации. Конкретно в случае с Ferra.ru я запрашивал у главреда разрешение на использование скрейпера.

Короче, по каждому из четырёх пунктов стоит ответить полноценной статьёй :)
astur
+1
Ну, про НКА стоит думать на этапе написания чего-то вроде cheerio или, например, lxml, а на этапе скрейпинга просто используется готовый парсер по принципу чёрного ящика.

Анализ наличия нужной информации — это довольно абстрактная тема, так как признаки нужности могут быть очень разными. Что-то можно проверить простенькой регуляркой, а что-то нужно прогонять через мощный синтаксический анализатор на НКА.