Как лучше всего очистить данные с веб-сайта? [закрыто]

107

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

Я нашел полезный сторонний инструмент под названием Import.io, который обеспечивает функциональность щелчка и перехода для очистки веб-страниц и создания наборов данных, единственное, что я хочу хранить свои данные локально, и я не хочу подписываться на какие-либо планы подписки .

Какие методы использует эта компания для очистки веб-страниц и создания их наборов данных? Я нашел несколько фреймворков для очистки веб-страниц pjscrape и Scrapy, могут ли они предоставить такую ​​функцию

0x1ad2
источник
4
PHP, конечно, не исключен, это явно неправильно. gist.github.com/krakjoe/b1526fcc828621e840cb
Джо Уоткинс
@JoeWatkins выглядит действительно круто, нужна ли ему специальная конфигурация PHP для запуска? И какова производительность по сравнению с инструментами / языками, представленными ниже?
0x1ad2 06
1
Для этого требуется поточно-безопасная сборка PHP и pthreads, прочтите github.com/krakjoe/pthreads/blob/master/README.md , вы можете найти меня в чате, если вам нужна помощь, я или кто-то еще :)
Джо Уоткинс
@ 0x1ad2 Если вы хотите хранить данные локально, вам следует попробовать программное обеспечение ( datascraping.co ) вместо веб-API. Большинство инструментов используют Xpath, CSS-селектор и REGEX для извлечения данных с веб-сайтов, а Data Scraping Studio поддерживает все эти 3 функции.
Викаш Рати,
Есть два способа: один - развернуть свой собственный, используя бесплатные библиотеки с открытым исходным кодом, что требует больших усилий. Вы можете буквально сгенерировать веб-сканер ajax для любого сайта с помощью scrape.it. Это платный инструмент, но он работал, когда ни один из бесплатных инструментов, таких как import.io или кимоно, не мог отрисовывать.
I Love Python

Ответы:

271

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

Примечание. Я использую здесь термины "сканирование" и "очистка", которые в основном взаимозаменяемы. Это копия моего ответа на ваш вопрос с Quora, он довольно длинный.

инструменты

Познакомьтесь с инструментами разработчика Firebug или Chrome в зависимости от вашего предпочтительного браузера. Это будет абсолютно необходимо, когда вы просматриваете сайт, с которого получаете данные, и определяете, какие URL-адреса содержат данные, которые вы ищете, и какие форматы данных составляют ответы.

Вам понадобится хорошее практическое знание HTTP, а также HTML, и, вероятно, вы захотите найти достойного человека в программном обеспечении промежуточного прокси. Вам нужно будет уметь проверять HTTP-запросы и ответы и понимать, как передаются файлы cookie, информация о сеансе и параметры запроса. Fiddler ( http://www.telerik.com/fiddler ) и Charles Proxy ( http://www.charlesproxy.com/ ) - популярные инструменты. Я часто использую mitmproxy ( http://mitmproxy.org/ ), так как я больше разбираюсь в клавишах, чем в мышах.

Неоценимое значение будет иметь какая-то среда типа console / shell / REPL, где вы можете опробовать различные фрагменты кода с мгновенной обратной связью. Подобные задачи обратного инжиниринга - это множество методов проб и ошибок, поэтому вам понадобится рабочий процесс, который упростит это.

Язык

PHP практически отсутствует, он не очень подходит для этой задачи, и поддержка библиотек / фреймворков в этой области оставляет желать лучшего. Python (Scrapy - отличная отправная точка) и Clojure / Clojurescript (невероятно мощный и производительный, но требующий большого обучения) - отличные языки для решения этой проблемы. Поскольку вы не хотите изучать новый язык и уже знаете Javascript, я определенно предлагаю придерживаться JS. Я не использовал pjscrape, но после быстрого чтения их документации он выглядит неплохо. Он хорошо подходит и представляет собой отличное решение проблемы, которую я описываю ниже.

Замечание о регулярных выражениях: НЕ ИСПОЛЬЗУЙТЕ ОБЫЧНЫЕ ВЫРАЖЕНИЯ ДЛЯ РАЗБОРА HTML. Многие новички делают это, потому что они уже знакомы с регулярными выражениями. Это огромная ошибка, используйте селекторы xpath или css для навигации по html и используйте только регулярные выражения для извлечения данных из фактического текста внутри узла html. Это может быть уже очевидно для вас, это становится очевидным быстро, если вы попробуете это, но многие люди по какой-то причине тратят много времени, идя по этому пути. Не бойтесь селекторов xpath или css, их НАМНОГО легче изучить, чем регулярные выражения, и они были разработаны для решения именно этой проблемы.

Сайты с большим количеством Javascript

Раньше вам просто нужно было сделать http-запрос и проанализировать HTML-ответ. Теперь вам почти наверняка придется иметь дело с сайтами, которые представляют собой смесь стандартных HTTP-запросов / ответов HTML и асинхронных HTTP-вызовов, выполняемых javascript-частью целевого сайта. Здесь вам очень пригодятся ваше программное обеспечение прокси и вкладка сети в firebug / devtools. Ответы на них могут быть html или json, в редких случаях это будет xml или что-то еще.

Есть два подхода к этой проблеме:

Подход низкого уровня:

Вы можете выяснить, какие URL-адреса ajax вызывает javascript сайта и как выглядят эти ответы, и самостоятельно выполнить те же запросы. Таким образом, вы можете вытащить html из http://example.com/foobar и извлечь один фрагмент данных, а затем получить ответ json из http://example.com/api/baz?foo=b ... в получить другую часть данных. Вам необходимо знать о передаче правильных файлов cookie или параметров сеанса. Это очень редко, но иногда некоторые обязательные параметры для вызова ajax будут результатом каких-то сумасшедших вычислений, сделанных в javascript сайта, обратное проектирование это может раздражать.

Подход со встроенным браузером:

Почему вам нужно выяснить, какие данные находятся в HTML и какие данные поступают в результате вызова ajax? Управляете всей этой сессией и данными cookie? Вам не обязательно делать это при просмотре сайта, браузер и сайт javascript делают это. В этом весь смысл.

Если вы просто загрузите страницу в безголовый движок браузера, такой как phantomjs, он загрузит страницу, запустит javascript и сообщит вам, когда все вызовы ajax будут завершены. Вы можете ввести свой собственный javascript, если необходимо, чтобы вызвать соответствующие клики или что-то еще, что необходимо для запуска javascript сайта для загрузки соответствующих данных.

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

Какой подход лучше?

Это зависит от того, что вам обязательно нужно знать и комфортно использовать низкоуровневый подход. Подход со встроенным браузером работает для чего угодно, его будет намного проще реализовать и он устранит некоторые из самых сложных проблем при парсинге. Это также довольно сложный механизм, который вам необходимо понять. Это не просто HTTP-запросы и ответы, это запросы, рендеринг встроенного браузера, javascript сайта, внедренный javascript, ваш собственный код и двустороннее взаимодействие со встроенным процессом браузера.

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

Ограничение скорости / поведение бота

Вы должны хорошо это осознавать. Вам нужно делать запросы к вашим целевым доменам по разумной цене. При сканировании веб-сайтов вам необходимо написать хорошо работающего бота, а это значит, что нужно уважать robots.txt и не забивать сервер запросами. Ошибки или халатность здесь очень неэтичны, так как это можно рассматривать как атаку отказа в обслуживании. Приемлемая скорость варьируется в зависимости от того, кого вы спрашиваете, 1 запрос / с - это максимум, на котором работает поисковый робот Google, но вы не Google и, вероятно, вас не так приветствуют, как Google. Делайте это как можно медленнее. Я бы предложил 2-5 секунд между каждым запросом страницы.

Идентифицируйте свои запросы с помощью строки пользовательского агента, которая идентифицирует вашего бота и имеет веб-страницу для вашего бота, объясняющую его цель. Этот URL входит в строку агента.

Вас легко заблокировать, если сайт захочет заблокировать вас. Умный инженер со своей стороны может легко идентифицировать ботов, и несколько минут работы с их стороны могут привести к неделям работы, изменяющей ваш код парсинга на вашей стороне, или просто сделать это невозможным. Если отношения антагонистические, то умный инженер на целевой площадке может полностью остановить гениального инженера, пишущего сканер. Код соскабливания по своей природе хрупок, и этим легко воспользоваться. Что-то, что может спровоцировать такой ответ, в любом случае почти наверняка неэтично, поэтому напишите бота с хорошим поведением и не беспокойтесь об этом.

Тестирование

Не тестируете модуль / интеграцию? Жаль. Теперь вам придется стать одним из них. Сайты часто меняются, и вы будете часто менять свой код. Это большая часть проблемы.

В парсинге современного веб-сайта задействовано множество движущихся частей, и хорошие методы тестирования очень помогут. Многие из ошибок, с которыми вы столкнетесь при написании этого типа кода, будут типа, который просто возвращает поврежденные данные без уведомления. Без хороших тестов для проверки регрессий вы обнаружите, что некоторое время сохраняли бесполезные поврежденные данные в своей базе данных, не замечая этого. Этот проект познакомит вас с проверкой данных (найдите несколько хороших библиотек для использования) и тестированием. Есть не так много других проблем, которые сочетают в себе необходимость всестороннего тестирования и очень сложную проверку.

Вторая часть ваших тестов включает кеширование и обнаружение изменений. При написании кода вы не хотите снова и снова без причины забивать сервер одной и той же страницей. При выполнении модульных тестов вы хотите знать, не работают ли тесты из-за того, что вы нарушили код или потому что веб-сайт был переработан. Запустите свои модульные тесты для кешированной копии задействованных URL-адресов. Кеширующий прокси-сервер здесь очень полезен, но его сложно настроить и правильно использовать.

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

Проблемы с законом

Здесь закон может быть немного опасным, если вы будете делать глупости. Если вмешивается закон, вы имеете дело с людьми, которые регулярно называют wget и curl «инструментами взлома». Вы этого не хотите.

Этическая реальность ситуации заключается в том, что нет никакой разницы между использованием программного обеспечения браузера для запроса URL-адреса и просмотра некоторых данных и использованием вашего собственного программного обеспечения для запроса URL-адреса и просмотра некоторых данных. Google - крупнейшая в мире компания по скрапингу, и их любят за это. Идентификация имени вашего бота в пользовательском агенте и открытость в отношении целей и намерений вашего веб-сканера помогут здесь, поскольку закон понимает, что такое Google. Если вы делаете что-то сомнительное, например, создаете фальшивые учетные записи пользователей или получаете доступ к областям сайта, которые вам не следует (либо «заблокированы» файлом robots.txt, либо из-за какой-либо уязвимости авторизации), то имейте в виду, что вы делаете что-то неэтичное. и незнание технологий законом будет здесь чрезвычайно опасно. Ситуация смешная, но реальная.

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

Кто я такой, чтобы писать эту гигантскую стену текста?

За свою жизнь я написал много кода, связанного со сканированием Интернета. Я занимаюсь разработкой программного обеспечения для Интернета более десяти лет в качестве консультанта, сотрудника и основателя стартапа. Сначала писали сканеры / парсеры Perl и веб-сайты на PHP. Когда мы встраивали скрытые фреймы, загружающие csv-данные на веб-страницы для выполнения ajax, до того, как Джесси Джеймс Гаррет назвал его ajax, до появления идеи XMLHTTPRequest. До jQuery, до json. Мне уже за тридцать, это, по-видимому, считается древним для этого бизнеса.

Я дважды писал крупномасштабные системы сканирования / очистки: один раз для большой команды в медиа-компании (на Perl) и недавно для небольшой команды в качестве технического директора запуска поисковой системы (на Python / Javascript). В настоящее время я работаю консультантом, в основном кодирую на Clojure / Clojurescript (замечательный экспертный язык в целом, и в нем есть библиотеки, которые делают проблемы сканера / парсера в восторге)

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

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

Джесси Шерлок
источник
4
Раньше я соглашался с вами в том, что PHP - плохой выбор, но с правильными библиотеками это не так уж плохо. Манипуляции с регулярными выражениями и массивами / жалами неуклюжи, но с другой стороны, они быстрые и везде.
pguardiario 05
3
В среде, где есть несколько библиотек, которые делают это удовольствие, и множество, которые делают это довольно просто и довольно легко ... зачем вам довольствоваться «не так уж плохо». Я согласен, это выполнимо в PHP (и FORTRAN, C, VB и т. Д.), Но если ваша проблема действительно не очень проста, было бы гораздо лучше использовать правильные инструменты для работы. И снова, если у вас нет невероятно простой проблемы, которую нужно решить ... какое значение имеет регулярное выражение везде? Установка библиотек намного проще, чем почти любая проблема со очисткой. И на самом деле регулярное выражение часто довольно медленно для этой проблемы.
Джесси Шерлок
5
Возможно , вы правы, но я знаю , за то , что я не могу сделать это , как легко в PHP. До того, как я ушел с PHP, у меня был почти десятилетний профессиональный опыт работы с PHP. Я потратил больше года на создание масштабной системы парсинга на Python, и я не могу себе представить, чтобы обойтись без некоторых хороших библиотек, которые недоступны в PHP, или без кратких методов метапрограммирования, доступных в Python. . По этой же причине я перешел на Clojure, чтобы получить еще более мощные возможности метапрограммирования.
Джесси Шерлок
4
Enlive, а также возможности самого Clojure для кода конкретного проекта, являются крупнейшими победителями. Schema - отличная библиотека для проверки, которая является такой большой частью кода извлечения информации. В настоящее время я очень доволен простым взаимодействием с миром Java для таких вещей, как Mahout, а также Nashorn / Rhino для некоторых видов выполнения js. И люди Clojure - это люди, которые пишут библиотеки вроде этой github.com/shriphani/subotai, так что вам не нужно. ... продолжение в следующем комментарии ...
Джесси Шерлок
3
Я также обнаружил, что, когда вам действительно нужен настоящий браузер и вам нужно использовать phantomjs / casperjs, действительно здорово использовать clojurescript (часто код, совместно используемый clj и cljs с использованием cljx), чтобы писать js, которые вы вводите на страницу, вместо clojurescript . Core.async отлично подходит для координирования параллельного сканирования кода на сервере, а также для выхода из ада обратных вызовов внутри среды js (координация автоматизации браузера с кодом core.async cljs внутри phantomjs - рай по сравнению с альтернативами).
Джесси Шерлок
21

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

Возможны разные варианты. Хорошая комбинация - это использование python-запросов (построенных поверх urllib2, это urllib.requestна Python3) и BeautifulSoup4 , у которого есть свои методы для выбора элементов, а также разрешены селекторы CSS :

import requests
from BeautifulSoup4 import BeautifulSoup as bs
request = requests.get("http://foo.bar")
soup = bs(request.text) 
some_elements = soup.find_all("div", class_="myCssClass")

Некоторые предпочтут синтаксический анализ xpath или jquery-подобные pyquery, lxml или что-то еще .

Когда нужные данные создаются с помощью JavaScript , вышеуказанное не сработает. Вам нужен либо python-ghost, либо Selenium. Я предпочитаю последний в сочетании с PhantomJS , он намного легче и проще в установке и прост в использовании:

from selenium import webdriver
client = webdriver.PhantomJS()
client.get("http://foo")
soup = bs(client.page_source)

Я бы посоветовал начать свое собственное решение. Так вы поймете преимущества Scrapy.

ps: внимательно посмотрите на: https://github.com/scrapy/scrapely

pps: взгляните на Portia, чтобы начать извлекать информацию визуально, без знания программирования: https://github.com/scrapinghub/portia

Эхвинс
источник
Хорошо, спасибо за anwser, единственная проблема в том, что Python не входит в мои навыки. Есть ли другие хорошие языки программирования, которые могли бы выполнять те же задачи? В основном работаю с PHP и Javascript.
0x1ad2 04
Извините за путаницу (я упомянул фреймворк Python в своем вопросе), но если Python - лучший способ сделать это, я мог бы его изучить.
0x1ad2 04
Python делает scrapy очень простым. Также легко научиться. Лучший скребок, который хорошо работает на данный момент, - это скребок. У них также есть очень хорошая документация.
Abhishek