Чем веб-пауки отличаются от пауков Wget?
Следующее предложение привлекло мое внимание в руководстве 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.
Я нахожу следующие строки кода, относящиеся к опции паука в 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 в коде?
4 ответа
Настоящий паук - это много работы
Написание паука для всей WWW - довольно сложная задача - вам нужно позаботиться о многих "маленьких деталях", таких как:
- Каждый компьютер-паук должен получать данные от нескольких тысяч серверов параллельно, чтобы эффективно использовать пропускную способность соединения. (асинхронный сокет ввода / вывода).
- Вам нужно несколько компьютеров, которые работают параллельно, чтобы охватить огромное количество информации о WWW (кластеризация; разделение работы).
- Вы должны быть вежливы с веб-сайтами:
- Уважайте файлы robots.txt.
- Не извлекайте слишком много информации слишком быстро: это перегружает серверы.
- Не выбирайте файлы, которые вам действительно не нужны (например, образы дисков iso; пакеты tgz для загрузки программного обеспечения...).
- Вам приходится иметь дело с файлами cookie / идентификаторами сеансов. Многие сайты прикрепляют уникальные идентификаторы сеансов к URL-адресам для идентификации сеансов клиентов. Каждый раз, когда вы заходите на сайт, вы получаете новый идентификатор сеанса и новый виртуальный мир страниц (с тем же содержанием). Из-за таких проблем ранние поисковые системы игнорировали динамический контент. Современные поисковые системы узнали, что такое проблемы и как с ними бороться.
- Вы должны обнаруживать и игнорировать проблемные данные: соединения, которые предоставляют бесконечное количество данных или соединений, которые слишком медленны для завершения.
- Помимо следующих ссылок, вы можете проанализировать карты сайта, чтобы получить URL-адреса страниц.
- Возможно, вы захотите оценить, какая информация важна для вас и часто меняется, чтобы обновляться чаще, чем другие страницы. Примечание: паук для всей WWW получает много данных - вы платите за эту пропускную способность. Вы можете использовать запросы HTTP HEAD, чтобы угадать, изменилась страница или нет.
- Помимо получения, вы хотите обрабатывать информацию и хранить ее. Google строит индексы, которые перечисляют для каждого слова страницы, которые его содержат. Вам могут понадобиться отдельные компьютеры хранения и инфраструктура для их подключения. Традиционные реляционные базы данных не соответствуют требованиям к объему данных и производительности для хранения / индексации всего WWW.
Это много работы. Но если ваша цель скромнее, чем чтение всей WWW, вы можете пропустить некоторые части. Если вы просто хотите скачать копию вики и т. Д., Вы переходите к спецификациям wget.
Примечание: если вы не верите, что это так много работы, вы можете прочитать о том, как Google заново изобрел большинство вычислительных колес (поверх базового ядра Linux) для создания хороших пауков. Даже если вы срезаете много углов, это большая работа.
Позвольте мне добавить еще несколько технических замечаний по трем пунктам.
Параллельные соединения / асинхронная сокетная связь
Вы можете запустить несколько программ-пауков в параллельных процессах или потоках. Но вам нужно около 5000-10000 параллельных соединений, чтобы эффективно использовать сетевое соединение. И такое количество параллельных процессов / потоков создает слишком много накладных расходов.
Лучшее решение - асинхронный ввод / вывод: обработайте около 1000 параллельных соединений в одном потоке, открыв сокеты в неблокирующем режиме, и используйте epoll или выберите для обработки только те соединения, которые получили данные. Начиная с ядра Linux 2.4, Linux имеет отличную поддержку масштабируемости (я также рекомендую изучать файлы с отображением в памяти), постоянно улучшающуюся в более поздних версиях.
Примечание. Использование асинхронного ввода-вывода помогает гораздо больше, чем использование "быстрого языка": лучше написать процесс, управляемый epoll для 1000 соединений, написанных на Perl, чем для запуска 1000 процессов, написанных на C. Если вы все сделаете правильно, вы можете насыщать 100 Мб соединения процессами, написанными на Perl.
Исходный ответ: Недостатком этого подхода является то, что вам придется реализовывать HTTP-спецификацию самостоятельно в асинхронной форме (я не знаю о библиотеке многократного использования, которая делает это). Это гораздо проще сделать с помощью более простого протокола HTTP/1.0, чем современный протокол HTTP/1.1. Вероятно, вы все равно не воспользуетесь преимуществами HTTP/1.1 для обычных браузеров, так что это может быть хорошим местом для экономии затрат на разработку.
Отредактируйте пять лет спустя: сегодня существует множество бесплатных / открытых технологий, которые могут помочь вам в этой работе. Мне лично нравится асинхронная http-реализация node.js - она спасает вас от всей работы, упомянутой в предыдущем абзаце. Конечно, сегодня есть также много доступных модулей для других компонентов, которые вам нужны в вашем пауке. Обратите внимание, однако, что качество сторонних модулей может значительно различаться. Вы должны проверить все, что вы используете. [Информация о старении:] Недавно я написал паук с использованием node.js и обнаружил, что надежность модулей npm для обработки HTML для извлечения ссылок и данных недостаточна. Для этой работы я "передал" эту обработку процессу, написанному на другом языке программирования. Но все быстро меняется, и к тому времени, как вы прочтете этот комментарий, эта проблема может уйти в прошлое...
Разбивка работы на несколько серверов
Один компьютер не может угнаться за паутинкой всей WWW. Вы должны распределить свою работу по нескольким серверам и обмениваться информацией между ними. Я предлагаю назначить определенные "диапазоны доменных имен" каждому серверу: сохранить центральную базу данных доменных имен со ссылкой на компьютер-паук.
Извлечение URL-адресов из полученных веб-страниц в пакетном режиме: сортируйте их по доменным именам; удалите дубликаты и отправьте их ответственному компьютеру-пауку. На этом компьютере сохраните индекс уже выбранных URL-адресов и извлеките оставшиеся URL-адреса.
Если вы сохраняете очередь URL-адресов, ожидающих извлечения на каждом компьютере-пауке, у вас не будет узких мест в производительности. Но для этого достаточно много программирования.
Читайте стандарты
Я упомянул несколько стандартов (HTTP/1.x, Robots.txt, Cookies). Не торопитесь, чтобы прочитать их и осуществить их. Если вы просто будете следовать примерам сайтов, которые вы знаете, вы допустите ошибки (забудете те части стандарта, которые не относятся к вашим образцам) и создадите проблемы для тех сайтов, которые используют эти дополнительные функции.
Больно читать стандартный документ HTTP/1.1. Но все мелкие детали были добавлены к нему, потому что кому-то действительно нужны эти маленькие детали, и теперь они ими пользуются.
Я не уверен точно, на что ссылался первоначальный автор комментария, но я могу предположить, что wget медленен как паук, поскольку он, похоже, использует только один поток выполнения (по крайней мере, из-за того, что вы показали).
"Настоящие" пауки, такие как heritrix, используют много параллелизма и трюков, чтобы оптимизировать скорость своего сканирования, и в то же время приятны для сайта, который они сканируют. Обычно это означает ограничение количества посещений одного сайта со скоростью 1 в секунду (или около того) и одновременное сканирование нескольких сайтов.
Опять же, это всего лишь предположение, основанное на том, что я знаю о пауках в целом, и что вы разместили здесь.
К сожалению, многие из наиболее известных "настоящих" веб-пауков имеют закрытый исходный код и действительно являются закрытыми двоичными файлами. Однако существует ряд базовых приемов, которые отсутствуют в wget:
- Параллелизм; вы никогда не сможете быть в курсе всего Интернета, не извлекая сразу несколько страниц
- приоритезация; некоторые страницы более важны для паука, чем другие
- Ограничение скорости; вас быстро забанят, если вы продолжите тянуть страницы так быстро, как сможете
- Сохранение чего-либо другого, кроме локальной файловой системы; Сеть достаточно велика, чтобы не поместиться в одном дереве каталогов.
- Периодически перепроверять страницы без перезапуска всего процесса; на практике, с настоящим пауком вы захотите часто проверять "важные" страницы на предмет обновлений, в то время как менее интересные страницы могут уходить месяцами.
Есть также различные другие входные данные, которые могут быть использованы, такие как карты сайта и тому подобное. Дело в том, что wget не предназначен для паутинки во всей сети, и это не та вещь, которая может быть захвачена в небольшом примере кода, так как это проблема всей используемой техники в целом, а не какой-то одной маленькой подпрограммы, являющейся неправильной для задачи.
Я не буду вдаваться в подробности того, как сделать паук в интернете, я думаю, что комментарий wget касается паутинга одного сайта, который все еще является серьезной проблемой.
- Как паук, вы должны выяснить, когда остановиться, а не переходить к рекурсивному сканированию только потому, что URL-адрес изменился с даты =1/1/1900 на 1/2/1900 и т. Д.
- Еще сложнее разобраться с переписыванием URL (я понятия не имею, как это происходит с Google или другими). Это довольно большая проблема, чтобы ползти достаточно, но не слишком много. И как можно автоматически распознать URL Rewrite с некоторыми случайными параметрами и случайными изменениями в контенте?
- Вам нужно разобрать Flash / Javascript хотя бы до какого-то уровня
- Вы должны рассмотреть некоторые сумасшедшие проблемы HTTP, такие как базовый тег. Даже анализ HTML не прост, учитывая, что большинство веб-сайтов не XHTML, а браузеры настолько гибки в синтаксисе.
Я не знаю, сколько из них реализовано или рассмотрено в wget, но вы, возможно, захотите взглянуть на httrack, чтобы понять проблемы этой задачи.
Я хотел бы дать вам несколько примеров кода, но это большие задачи, и приличный паук будет около 5000 loc без сторонних библиотек.
+ Некоторые из них уже объяснены @yaakov-belch, поэтому я не собираюсь их снова печатать