Сканирование определенных страниц и данных и их поиск

Важное примечание: приведенные ниже вопросы не предназначены для нарушения ЛЮБЫХ авторских прав на данные. Все обходные и сохраненные данные напрямую связаны с источником.


Привет, ребята!

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

Прежде всего, мне нужно пояснить, что клиент собирается предоставить список сайтов, которые будут проиндексированы. Итак, на самом деле, вертикальная поисковая система. Результаты должны иметь только ссылку, название и описание (например, как Google показывает результаты). Основная цель этой поисковой системы - облегчить посетителям поиск большого количества сайтов и результатов, чтобы найти то, что им нужно. So: Веб-сайт A содержит кучу ссылок → сохранить все ссылки вместе с метаданными.

Во-вторых, существует более конкретная поисковая система. Тот, который также индексирует все ссылки на статьи (пусть их называют), эти статьи распространяются на многие более мелкие сайты с меньшим количеством статей по сравнению с сайтами, которые попадают в вертикальную поисковую систему. Причина проста: статьи, найденные на этих страницах, должны быть очищены как можно больше деталей. Здесь возникает первая проблема: для написания скребка для каждого веб-сайта потребуется огромное количество времени, данные, которые необходимо собрать, например: название города, дата статьи, название статьи. So: Веб-сайт B содержит более подробные статьи, чем веб-сайт A, мы собираемся индексировать эти статьи и извлекать полезные данные.

У меня есть метод, который может работать, но это требует написания скребка для каждого отдельного веб-сайта, на самом деле это единственное решение, о котором я могу думать прямо сейчас. Поскольку DOM каждой страницы полностью различен, я не вижу возможности построить алгоритм с проверкой дурака, который ищет DOM и "знает", какая часть страницы является местоположением (однако... это возможность, если вы можете сопоставить текст против полного списка городов).

Несколько вещей, которые приходили мне в голову:

Вертикальная поисковая система

  • Для вертикальной поисковой системы это довольно прямолинейно, у нас есть список веб-страниц, которые нужно индексировать, должно быть довольно просто обходить все страницы, соответствующие регулярному выражению, и хранить полный список этих URL-адресов в базе данных,
  • Я бы хотел разделить сохраненные данные страницы (метаописание, название и т.д.) в отдельный процесс, чтобы ускорить индексирование.
  • Существует вероятность того, что в этой поисковой системе будут дублироваться данные из-за сайтов, которые имеют соответствующие результаты/статьи. Я не думал о том, как фильтровать эти дубликаты, возможно, в заголовке статьи, но в бизнес-сегменте, где данные поступают оттуда, огромные изменения в дубликатах, но разные статьи.

Скребок страницы

  • Индексирование "готовых" страниц может быть сделано аналогичным образом, если мы знаем, какое регулярное выражение должно соответствовать URL-адресам. Мы можем сохранить список URL-адресов в базе данных
  • Используйте отдельный процесс, который запускает все отдельные страницы, на основе URL-адреса, скребок должен теперь использовать какое-то регулярное выражение для соответствия требуемым деталям на странице и записать их в базу данных
  • Достаточно сайтов, которые уже индексируют результаты, поэтому я предполагаю, что должен существовать способ создания алгоритма скремблирования, который знает, как читать страницы, не полностью совпадающие с регулярным выражением. Как я уже говорил: если у меня есть полный список названий городов, должна быть возможность использовать алгоритм поиска, чтобы получить название города, не сказав the city name lies in "#content .about .city".

Резервирование данных

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

Устранимость данных проще с помощью скребка страницы, так как мой клиент составил список "хороших источников" (читайте: страницы с уникальными статьями). Уверенность данных для вертикальной поисковой системы сложнее, потому что индексируемые сайты уже делают свой собственный выбор произведений искусства из "хороших источников". Таким образом, есть вероятность, что несколько сайтов имеют выбор из тех же источников.


Как сделать результаты поиска

Это вопрос, отличный от того, как сканировать и очищать страницы, потому что, как только все данные будут храниться в базе данных, его нужно искать с высокой скоростью. Объем данных, которые будут сохранены, по-прежнему неизвестен, по сравнению с некоторыми конкурентами у моего клиента было указание около 10 000 мелких записей (вертикальный поиск) и, возможно, 4000 больших записей с более подробной информацией.

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

До сих пор я нашел SphinxSearch и ElasticSearch. Я не работал ни с одним из них, и на самом деле я не изучил возможности обоих. Единственное, что я знаю, это то, что оба должны хорошо работать с большими объемами и большими поисковыми запросами в данных.


Подводя итог

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

  • Есть ли простой способ создать алгоритм поиска, способный сопоставлять данные DOM без указания точного div, в котором находится контент?
  • Какова наилучшая практика для обхода страниц (ссылки, название и описание).
  • Должен ли я разделить обход URL-адресов и сохранить название страницы/описание скорости?
  • Есть ли готовые решения для PHP для поиска (возможных) дубликатов данных в базе данных (даже если есть небольшие различия, например: если 80% совпадений → отмечают как дубликаты)
  • Каков наилучший способ создания поисковой системы будущего поиска для данных (помните, что количество данных может увеличиваться как трафик сайта и поисковые запросы).

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

Ответ 1

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

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

Для меня это означало создание 3 отдельных разделов:

  • Менеджер веб-скребка

  • Веб-скребок

  • Процессор HTML

Затем работу можно разделить так:

1) Диспетчер веб-скребок

Диспетчер веб-скрепок извлекает URL-адрес, который нужно очистить, и создаст веб-скребки. Менеджер веб-скребка должен указывать все URL-адреса, которые были отправлены на веб-скребки, так как они "активно очищаются" и знают, что они не сбрасывают их снова, пока они находятся в этом состоянии. После получения сообщения от скребок менеджер либо удалит строку, либо оставит ее в состоянии "активно очищенной", если ошибок не произошло, иначе она будет reset вернуться к "неактивной"

2) Веб-скребок

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

ID | URL | HTML (BLOB) | ОБРАБОТКА

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

3) Процессор HTML

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

После того, как все соответствующие данные будут проанализированы, процессор HTML отправит все эти данные в кластер ElasticSearch. ElasticSearch обеспечивает быстрый поиск полного текста, который можно сделать еще быстрее, разбив данные на различные клавиши:

{ 
   "url" : "http://example.com",
   "meta" : {
       "title" : "The meta title from the page",
       "description" : "The meta description from the page",
       "keywords" : "the,keywords,for,this,page"
   },
   "body" : "The body content in it entirety",
   "images" : [
       "image1.png",
       "image2.png"
   ]
}

Теперь ваш сайт/служба может иметь доступ к последним данным в режиме реального времени. Анализатор должен быть достаточно подробным для обработки любых ошибок, чтобы он мог установить флаг обработки в false, если он не может вытащить данные или, по крайней мере, зарегистрировать его где-нибудь, чтобы он мог быть просмотрен.

В чем преимущества?

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

Каковы недостатки?

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

Ответ 2

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

Вы можете постоянно сканировать ваши данные и обновлять остальные таблицы в фоновом режиме (каждые X минут/часов), чтобы ваши результаты поиска были свежими все время, но вам не придется ждать сканирование до конца.

Обход

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

ALL_DATA
____________________________________________
| Url | Title | Description | HTML_Content |
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

Таблицы и индексирование

Создайте большую таблицу, содержащую URL-адреса и ключевые слова

KEYWORDS
_________________
| URL | Keyword |
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

В этой таблице будет содержаться большинство слов в каждом содержимом URL (я бы удалил слова типа "the", "on", "with", "a" и т.д.

Создайте таблицу с ключевыми словами. Для каждого вхождения добавьте 1 в столбец вхождения

KEYWORDS
_______________________________
| URL | Keyword | Occurrences |
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

Создайте еще одну таблицу с "горячими" ключевыми словами, которая будет намного меньше

HOT_KEYWORDS
_________________
| URL | Keyword | 
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

Содержимое этой таблицы будет загружено позже в соответствии с поисковыми запросами. Наиболее распространенные слова поиска будут храниться в таблице HOT_KEYWORDS.

В другой таблице будут сохранены результаты поиска в кеше

CACHED_RESULTS
_________________
| Keyword | Url |
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

Алгоритм поиска

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

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

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

Ответ 3

  • Просто посмотрите Solr и solr-wiki. его поисковая платформа с открытым исходным кодом из проекта lucene (аналогично Elasticsearch).
  • Для веб-искателя вы можете использовать Aperture или Nutch. Оба написаны в java. Диафрагма - легкий гусеничный манипулятор. Но с Nutch мы можем сканировать еще 1000 веб-сайтов.
  • Nutch будет обрабатывать процесс сканирования для веб-сайтов. Более того Nutch предоставляет Solr поддержку. Это означает, что вы можете индексировать данные, сканированные с Nutch непосредственно в Solr.
  • Используя Solr Cloud, мы можем настроить несколько кластеров с чередованием и репликацией, чтобы предотвратить потерю данных и быстрое получение данных.

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

Ответ 4

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

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

Ответ 5

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

Здесь вы можете найти исходный код. Пожалуйста, помогите внести свой вклад:-) Это сфокусированный искатель, который действительно не делает ничего, кроме поиска сайтов и ранжирования их в соответствии с наличием ключевых слов. Его нельзя использовать для огромных нагрузок данных, но это неплохо подходит для поиска соответствующих сайтов.

https://github.com/herreovertidogrom/crawler.git

Это немного плохо документировано, но я обойдусь с этим.

Если вы хотите выполнять поиск обходных данных, и у вас много данных, и они стремятся построить будущую службу доказательств, вы НЕ должны создавать таблицу с N столбцами, по одному для каждого поискового запроса. Это общий дизайн, если вы считаете, что URL является основным ключом. Скорее, вам следует избегать широкоформатного дизайна, такого как вредитель. Это связано с тем, что чтение дисков IO становится невероятно медленным при разработке широкоформатных таблиц. Вместо этого вы должны хранить все данные в одной таблице, указать ключ и значение, а затем разбить таблицу на имя переменной.

Избегать дублирования всегда сложно. По моему опыту, из хранилища данных - создайте первичный ключ и дайте БД выполнить эту работу. Я пытаюсь использовать исходный + ключ + значение в качестве первичного ключа, что позволяет избежать двойного подсчета и имеет несколько ограничений.

Могу ли я предложить создать таблицу следующим образом:

URL, переменная, значение и сделать этот первичный ключ.

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

Ответ 6

Вы пробовали http://simplehtmldom.sourceforge.net/manual.htm? Я нашел, что это полезно для утилизации страниц, и может оказаться полезным поиск содержимого.

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

ElasticSearch будет полезно искать сохраненные данные.

Ответ 7

Вы можете выполнить поиск по HTML с помощью этого кода:

<? 
    //Get the HTML
    $page = file_get_html('http://www.google.com')

    //Parse the HTML
    $html = new DOMDocument();
    $html->loadHTML($page);

    //Get the elemnts you are intersted in... 
    $divArr = $html->getElementsByTagName('div');
    foreach($divArr as $div) {
        echo $div->nodeValue;
    }
?>