#python #multithreading #web-crawler #web-mining
#python #многопоточность #веб-поисковик #веб-майнинг
Вопрос:
Я хотел бы выполнить интеллектуальный анализ данных в больших масштабах. Для этого мне нужен быстрый поисковик. Все, что мне нужно, это что-то для загрузки веб-страницы, извлечения ссылок и рекурсивного перехода по ним, но без повторного посещения одного и того же URL-адреса. В принципе, я хочу избежать зацикливания.
Я уже написал поисковый робот на python, но он слишком медленный. Я не могу насытить им строку 100 Мбит. Максимальная скорость составляет ~ 40 URL-адресов в секунду. и по какой-то причине трудно получить лучшие результаты. Похоже, проблема с многопоточностью / сокетами python. Я также столкнулся с проблемами с коллектором gargabe в python, но это было решаемо. Процессор, кстати, не является узким местом.
Итак, что я должен использовать для написания сканера, который работает как можно быстрее, и каково наилучшее решение, чтобы избежать зацикливания во время обхода?
РЕДАКТИРОВАТЬ: решение состояло в том, чтобы объединить multiprocessing
threading
модули and . Для достижения наилучшего эффекта создайте несколько процессов с несколькими потоками для каждого процесса. Создание нескольких потоков в одном процессе неэффективно, а несколько процессов с одним потоком потребляют слишком много памяти.
Комментарии:
1. Вы не получите лучших результатов, используя многопоточность python после определенной точки из-за глобальной блокировки интерпретатора. Кроме того, я готов поспорить, что вы не сможете насытить 100-битную строку без получения дубликатов. Короче говоря, вы преждевременно оптимизируете.
2. Вы проверили Scrapy? Это довольно круто для такого рода вещей.. scrapy.org
3. @Falmarri: пожалуйста, поясните, почему вы думаете, что я не смогу насытить. Если страница имеет ~ 50 КБ в среднем, то мне нужно обрабатывать ~ 200 URL-адресов в секунду. для насыщения. Как вы думаете, это проблема?
4. Можете ли вы запускать несколько поисковых роботов одновременно?
5. @Falmarri: это неверно. Ваши рассуждения можно использовать, чтобы доказать, что невозможно насытить линии сколь угодно малой пропускной способностью (замените строку 1 Мбит на строку 100 Мбит).
Ответ №1:
Почему бы не использовать что-то уже протестированное для обхода, например Scrapy? Мне удалось разогнаться почти до 100 страниц в секунду на недорогом VPS с ограниченной оперативной памятью (около 400 Мб), в то время как скорость сети составляла около 6-7 Мб / с (т. Е. Ниже 100 Мбит / с).
Еще одно улучшение, которое вы можете сделать, это использовать urllib3
(особенно при сканировании многих страниц из одного домена). Вот краткое сравнение, которое я сделал некоторое время назад:
Обновить:
Теперь Scrapy использует библиотеку запросов, которая, в свою очередь, использует urllib3. Это делает Scrapy идеальным инструментом, когда дело доходит до очистки. Последние версии также поддерживают развертывание проектов, поэтому очистка от VPS проще, чем когда-либо.
Комментарии:
1. 100 страниц для определенного (одного) домена?
2. Да, 100 страниц для одного домена, размещенного в той же стране, что и сам поисковый робот (Германия).
3. Scrapy никогда не использовал модуль запросов, потому что Scrapy написан поверх Twisted . Хотя Scrapy подходит для большинства задач очистки, он мало поддерживает распределенный обход, что делает его несколько бесполезным для крупномасштабных обходов.
Ответ №2:
Около 2 лет назад я разработал поисковый робот. И он может загружать почти 250 кадров в секунду. Вы могли бы выполнять мои шаги.
- Оптимизируйте использование указателя на файл. Попробуйте использовать минимальный указатель на файл.
- Не записывайте свои данные каждый раз. Попробуйте сбросить свои данные после сохранения около 5000 url или 10000 url.
- Для вашей надежности вам не нужно использовать другую конфигурацию. Попробуйте использовать файл журнала, и когда вы захотите возобновить работу, просто попробуйте прочитать файл журнала и возобновить работу сканера.
-
Распределил всю вашу задачу webcrawler. И обрабатывайте его с интервалом.
a. downloader
b. экстрактор ссылок
c. URLSeen
d. ContentSeen
Ответ №3:
Я написал простой многопоточный поисковый робот. Он доступен на GitHub как поиск веб-ресурсов, и я написал соответствующую статью: Автоматическое обнаружение каналов блогов и учетных записей Twitter, Facebook, LinkedIn, подключенных к бизнес-сайту. Вы можете изменить количество используемых потоков в переменной класса NWORKERS. Не стесняйтесь задавать дополнительные вопросы, если вам нужна дополнительная помощь.
Ответ №4:
Похоже, у вас проблема дизайна больше, чем проблема языка. Попробуйте заглянуть в модуль многопроцессорной обработки для одновременного доступа к нескольким сайтам, а не к потокам. Кроме того, рассмотрите возможность получения некоторой таблицы для хранения ваших ранее посещенных сайтов (возможно, базы данных?).
Комментарии:
1. Помогло использование многопроцессорной обработки. С помощью 100 процессов я получаю ~ 20 Мбит трафика. Проблема заключается в загрузке памяти — интерпретатор python занимает ~ 7 МБ памяти, что очень много.
2. Ну, вы определенно используете слишком много процессов. Большинство параллельных алгоритмов порождают столько процессов, сколько у них ядер. Если вы тратите время на ожидание веб-сайтов, создайте еще несколько. Попытайтесь найти какой-то баланс, который обеспечивает высокую скорость страниц в секунду (возможно, также используйте Scrapy, как предлагали другие).
Ответ №5:
Невозможно определить, каковы ваши ограничения. Ваша проблема похожа на проблему C10K — сначала прочитайте, не оптимизируйте сразу. Выбирайте низко висящие плоды: скорее всего, вы получите значительное повышение производительности, проанализировав дизайн своего приложения. Не начинайте с многопоточных или многопроцессорных программ.
Я бы использовал Twisted для написания сетевой части, это может быть очень быстро. В общем, ввод-вывод на компьютере должен быть лучше среднего. Вам нужно либо записывать свои данные на диск, либо на другую машину, не каждый ноутбук поддерживает непрерывную запись в базу данных со скоростью 10 Мбайт / с. Наконец, если у вас асинхронное подключение к Интернету, возможно, ваш восходящий поток просто переполнен. Здесь помогает приоритизация ACK (пример OpenBSD).