Вопрос

Следующее предложение привлекло мое внимание в руководстве Wget

wget --spider --force-html -i bookmarks.html

This feature needs much more work for Wget to get close to the functionality of real web spiders.

Я нахожу следующие строки кода релевантными для опции spider в wget.

src/ftp.c
780:      /* If we're in spider mode, don't really retrieve anything.  The
784:      if (opt.spider)
889:  if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
1227:      if (!opt.spider)
1239:      if (!opt.spider)
1268:      else if (!opt.spider)
1827:          if (opt.htmlify && !opt.spider)

src/http.c
64:#include "spider.h"
2405:  /* Skip preliminary HEAD request if we're not in spider mode AND
2407:  if (!opt.spider
2428:      if (opt.spider && !got_head)
2456:      /* Default document type is empty.  However, if spider mode is
2570:           * spider mode.  */
2571:          else if (opt.spider)
2661:              if (opt.spider)

src/res.c
543:  int saved_sp_val = opt.spider;
548:  opt.spider       = false;
551:  opt.spider       = saved_sp_val;  

src/spider.c
1:/* Keep track of visited URLs in spider mode.
37:#include "spider.h"
49:spider_cleanup (void)

src/spider.h
1:/* Declarations for spider.c

src/recur.c
52:#include "spider.h"
279:      if (opt.spider)
366:              || opt.spider /* opt.recursive is implicitely true */
370:             (otherwise unneeded because of --spider or rejected by -R) 
375:                   (opt.spider ? "--spider" : 
378:                     (opt.delete_after || opt.spider
440:      if (opt.spider) 

src/options.h
62:  bool spider;           /* Is Wget in spider mode? */

src/init.c
238:  { "spider",           &opt.spider,            cmd_boolean },

src/main.c
56:#include "spider.h"
238:    { "spider", 0, OPT_BOOLEAN, "spider", -1 },
435:       --spider                  don't download anything.\n"),
1045:  if (opt.recursive && opt.spider)

Я хотел бы видеть различия в коде, а не абстрактно.Я люблю примеры кода.

Чем веб-пауки отличаются от Wget spider в коде?

Это было полезно?

Решение

Настоящий паук - это большая работа

Написание spider для всего WWW - довольно сложная задача - вам нужно позаботиться о многих "мелких деталях", таких как:

  • Каждый компьютер spider должен получать данные с нескольких тысяч серверов параллельно, чтобы эффективно использовать пропускную способность соединения.(асинхронный ввод-вывод сокета).
  • Вам нужно несколько компьютеров, работающих параллельно, чтобы охватить огромное количество информации на WWW (кластеризация;разделение работы)
  • Вы должны быть вежливы с зараженными веб-сайтами:
    • Уважайте файлы robots.txt.
    • Не извлекайте слишком много информации слишком быстро:это перегружает серверы.
    • Не извлекайте файлы, которые вам действительно не нужны (напримеробразы дисков iso;пакеты tgz для загрузки программного обеспечения ...).
  • Вам приходится иметь дело с файлами cookie / идентификаторами сеанса:Многие сайты прикрепляют уникальные идентификаторы сеансов к URL-адресам для идентификации клиентских сеансов.Каждый раз, когда вы заходите на сайт, вы получаете новый идентификатор сеанса и новый виртуальный мир страниц (с тем же содержимым).Из-за таких проблем ранние поисковые системы игнорировали динамический контент.Современные поисковые системы узнали, в чем заключаются проблемы и как с ними бороться.
  • Вы должны обнаруживать и игнорировать проблемные данные:соединения, которые предоставляют, казалось бы, бесконечный объем данных, или соединения, которые слишком медленно завершаются.
  • Помимо перехода по ссылкам, вы можете захотеть проанализировать карты сайта чтобы получить URL-адреса страниц.
  • Возможно, вы захотите оценить, какая информация важна для вас и часто меняется, чтобы обновляться чаще, чем на других страницах.Примечание:Паук для всего WWW получает много данных - вы платите за эту пропускную способность.Возможно, вы захотите использовать HTTP HEAD-запросы, чтобы угадать, изменилась страница или нет.
  • Помимо получения, вы хотите обработать информацию и сохранить ее.Google создает индексы, в которых для каждого слова перечислены страницы, которые его содержат.Возможно, вам понадобятся отдельные компьютеры для хранения данных и инфраструктура для их подключения.Традиционные реляционные базы данных не соответствуют требованиям к объему данных и производительности для хранения / индексирования всего WWW.

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

Примечание:Если вы не верите, что это так много работы, возможно, вы захотите прочитать о том, как Google заново изобрел большинство вычислительных колес (поверх базового ядра Linux) для создания хороших spiders.Даже если вы срезаете много углов, это большая работа.

Позвольте мне добавить еще несколько технических замечаний по трем пунктам

Параллельные соединения / асинхронная связь с сокетом

Вы могли бы запускать несколько программ-пауков в параллельных процессах или потоках.Но вам нужно около 5000-10000 параллельных подключений, чтобы эффективно использовать ваше сетевое соединение.И такое количество параллельных процессов / потоков создает слишком много накладных расходов.

Лучшим решением является асинхронный ввод / вывод:обработайте около 1000 параллельных подключений в одном потоке, открыв сокеты в неблокирующем режиме, и используйте epoll или select для обработки только тех подключений, которые получили данные.Начиная с ядра Linux 2.4, Linux имеет отличную поддержку масштабируемости (я также рекомендую вам изучить файлы с отображением в память), постоянно улучшаемую в более поздних версиях.

Примечание:Использование асинхронного ввода-вывода помогает гораздо больше, чем использование "быстрого языка".:Лучше написать процесс, управляемый epoll, для 1000 подключений, написанных на Perl, чем запускать 1000 процессов, написанных на C.Если вы сделаете это правильно, вы сможете насытить 100-мегабайтное соединение процессами, написанными на perl.

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

Редактировать пять лет спустя: Сегодня существует множество бесплатных технологий с открытым исходным кодом, которые помогут вам в этой работе.Лично мне нравится асинхронный реализация http из node.js --- это экономит вам всю работу, упомянутую в приведенном выше первоначальном абзаце.Конечно, сегодня также доступно множество модулей для других компонентов, которые вам нужны в вашем spider.Однако обратите внимание, что качество модулей сторонних производителей может значительно отличаться.Вы должны проверить все, что вы используете. [Информация о старении:] Недавно я написал spider, используя node.js и я обнаружил, что надежность модулей npm для обработки HTML для ссылки и извлечения данных недостаточна.Для этой работы я "передал" эту обработку на аутсорсинг процессу, написанному на другом языке программирования.Но все быстро меняется, и к тому времени, когда вы прочтете этот комментарий, эта проблема, возможно, уже уйдет в прошлое...

Распределение работы по нескольким серверам

Один компьютер не может угнаться за распространением пауков по всему WWW.Вам необходимо распределить свою работу по нескольким серверам и обмениваться информацией между ними.Я предлагаю назначить определенные "диапазоны доменных имен" каждому серверу:ведите центральную базу данных доменных имен со ссылкой на компьютер spider.

Извлекайте URL-адреса из полученных веб-страниц пакетными методами:отсортируйте их в соответствии с их доменными именами;удалите дубликаты и отправьте их на ответственный компьютер spider.На этом компьютере сохраните индекс URL-адресов, которые уже были выбраны, и извлеките остальные URL-адреса.

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

Ознакомьтесь со стандартами

Я упомянул несколько стандартов (HTTP/1.x, Robots.txt, файлы cookie).Потратьте время на то, чтобы прочитать их и внедрить в жизнь.Если вы просто будете следовать примерам сайтов, которые вам известны, вы будете совершать ошибки (забывать части стандарта, которые не имеют отношения к вашим образцам) и создавать проблемы для тех сайтов, которые используют эти дополнительные функции.

Читать стандартный документ HTTP / 1.1 - сплошная мука.Но все мелкие детали были добавлены к нему, потому что кому-то действительно нужна эта маленькая деталь, и теперь он ее использует.

Другие советы

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

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

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

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

  • Параллелизм;вы никогда не сможете быть в курсе всего Интернета, не извлекая одновременно несколько страниц
  • Расстановка приоритетов;некоторые страницы более важны для spider, чем другие
  • Ограничение скорости;вас быстро забанят, если вы будете продолжать удалять страницы так быстро, как только сможете
  • Сохранение во что-то другое, кроме локальной файловой системы;сеть достаточно велика, чтобы не поместиться в одном дереве каталогов
  • Периодическая перепроверка страниц без перезапуска всего процесса;на практике с настоящим spider вам захочется часто проверять "важные" страницы на наличие обновлений, в то время как менее интересные страницы могут отсутствовать месяцами.

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

Я не собираюсь вдаваться в подробности о том, как создать паутину в Интернете, я думаю, что комментарий wget касается создания паутины на одном веб-сайте, что по-прежнему является серьезной проблемой.

  • Как пауку, вам нужно выяснить, когда остановиться, а не переходить к рекурсивному обходу только потому, что URL изменился как date = 1/1/1900 на 1/2/1900 и так далее
  • Еще большая проблема - разобраться с переписыванием URL (я понятия не имею, что и как Google или любой другой обрабатывает это).Проползти достаточно сложно, но не слишком много.И как можно автоматически распознать перезапись URL-адреса с некоторыми случайными параметрами и случайными изменениями в содержимом?
  • Вам нужно разобрать Flash / Javascript хотя бы до некоторого уровня
  • Вам нужно рассмотреть некоторые сумасшедшие проблемы HTTP, такие как База пометка.Даже разобрать HTML непросто, учитывая, что большинство веб-сайтов не являются XHTML, а браузеры настолько гибки в синтаксисе.

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

Я бы с удовольствием привел вам несколько примеров кода, но это большие задачи, а приличный spider будет стоить около 5000 loc без сторонних библиотек.

+ Некоторые из них уже объяснены @yaakov-belch, поэтому я не собираюсь вводить их снова

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top