deltafetch, пусть поисковые роботы имеют память
предисловие
«Я превратилась в русалку, всего семь секунд памяти».
Много раз программа-краулер работала и давала сбой из-за сетевых сбоев или программных исключений. В отчаянии я могу только перезапуститься и снова ползти. Чтобы избежать этой ситуации перезапуска каждый раз, мы будем использовать mysql, redis, text и т. д. для записи просканированного URL-адреса.
Это также увеличивает общую сложность программы. Тем не менее, scrapy предоставляет модуль для решения этой проблемы, и только две строки конфигурации решают эту проблему.
Возобновить восхождение
В первой статье серии Scrapy я описал распространенную проблему сканирования сканерами.
Если нужно просканировать 1000 страниц, а просканирована 999-я страница, когда полоса прогресса вот-вот заполнится, программа зависнет по щелчку, всего один короткий, но еще не досканировала, что не так? Я выбираю перезапустить программу, так как мне начать ползать прямо с 999-го?
Позвольте мне рассказать о первом сканере, который я написал здесь: сканирование информации о пои более 10 городов.
17 лет стажировки, когда я впервые разработал краулер, я не знал, что существует интерфейс Gaode poi, поэтому я нашел веб-сайт для сканирования информации о poi. В то время веб-сайт, по оценкам, все еще находился в зачаточном состоянии, пропускная способность сервера не должна была быть высокой, скорость доступа была очень низкой, и он постоянно останавливался на техническое обслуживание, поэтому мою программу пришлось остановить соответственно. Если сканирование перезапускать каждый раз, когда оно запускается, считается, что сканирование не будет завершено через несколько лет, поэтому я придумал способ.
Сначала я вручную ввожу количество элементов данных всех районов и уездов по всем префектурам и городам (доступным на веб-сайте) в таблицу базы данных, и каждый раз, когда программа-краулер перезапускается, сначала подсчитываю элементы, которые были просканированы каждым района и округа в таблице данных результатов число, по сравнению с общим количеством записей. Если оно меньше, это означает, что сканирование не было завершено, а затем рассчитать количество страниц, которые я просканировал до этого района и округа, исходя из количества просканированных элементов в определенном районе/округе/количества отображаемых элементы на каждой странице веб-сайта , а затем используйте оставшуюся часть, чтобы найти страницу, которую я просканировал до номера этой страницы. Благодаря этому методу 163 Вт фрагментов данных были наконец просканированы без потерь.
Другой способ мышления - поместить просканированный URL-адрес в таблицу, а при перезапуске программы, чтобы начать сканирование URL-адреса, сначала определить, существует ли URL-адрес в таблице данных, если он существует, не сканировать, это также может обеспечить непрерывную точку останова. ползать . Это также следует идее дедупликации исходного URL-адреса.
Сегодня же, о чем пойдет речь, scrapy-deltafetch вообще не нуждается в рассмотрении вышеперечисленных проблем!
Scrapy-дельтафетч
Вышеприведенные две идеи имеют две общие черты:
- Вручную реализовать код логики точки останова
- Положитесь на внешнее хранилище/базу данных
Это увеличивает нагрузку на разработку. Итак, мы вводим здесь модуль scrapy-deltafecth, и две строки конфигурации могут идеально решить две вышеупомянутые проблемы.
принцип
deltch существует как промежуточное ПО Spider в Scrapy. Принцип заключается в том, чтобы создать встроенную базу данных KV BerkeleyDB, а при выполнении элемента yield зашифровать response.request как ключ и сохранить его во встроенной базе данных.
Таким образом, каждый раз, когда он сканируется, он будет обращаться к встроенной базе данных, чтобы определить, существует ли уже URL-адрес, и если он существует, он больше не будет сканироваться.
В это время кто-то скажет, разве это не все еще использует базу данных?
Существует разница между встроенной базой данных и базой данных:
- Встроенная база данных встроена в процесс приложения и работает в том же адресном пространстве, что и приложение, поэтому работа с базой данных не требует межпроцессного взаимодействия.
- Встроенная база данных — это файл данных с основными характеристиками базы данных. Он предоставляет набор API для доступа к файлу базы данных и управления им. Он напрямую управляется программой, а не ответом механизма.
Короче говоря, встроенная база данных не имеет собственной фоновой службы и механизма выполнения, такого как база данных MySQL.
установить дельтафетч
Способы установки deltafetch в средах Windows и Linux различаются, а установка под Linux сложнее.
Модуль deltafech зависит от модуля bsddb3, а bsddb3 должен зависеть от BerkeleyDB.
Установка Windows
Установка под Win относительно проста, и нет необходимости отдельно устанавливать BerkeleyDB. Используйте pip для прямой установки bsddb3.Если установка не удалась, загрузите установочную версию whl и установите ее отдельно. Затем установите scrapy-deltafetch.
Конкретный способ описывать не буду, в основном установка под Llinux.
установка линукс
Установка под Linux немного сложнее, нужно скачать Berkeley DB с официального сайта oracle, а потом скомпилировать и установить.
1. Загрузите и установите Berkeley DB.
Pro-test, не загружайте версию Berkeley DD v18, я использую версию 6.2.23.
# ,18版本不行,18.1.40会安装失败,18低版本在安装bsddb3时会报错
cd build_unix
../dist/configure --prefix=/usr/local/berkeleyDb
make & make install
2. Установите bsddb3
export BERKELEYDB_DIR=/usr/local/berkeleyDb
export YES_I_HAVE_THE_RIGHT_TO_USE_THIS_BERKELEY_DB_VERSION=yes
pip3 install bsddb3
3. Установите скрап-дельтафетч
pip3 install scrapy-deltafetch
Использование scrapy-deltafetch
1. Изменить settings.py
В settings.py добавьте промежуточное ПО deltafetch и активируйте его.
SPIDER_MIDDLEWARES = {
'scrapy_deltafetch.DeltaFetch': 100
}
# 开启
DELTAFETCH_ENABLED = True
Здесь следует отметить, что deltafetch — это промежуточное программное обеспечение паука.Согласно диаграмме архитектуры, паук будет запущен только тогда, когда элемент yield достигнет конвейера, поэтому только элемент yield может заставить deltafetch вступить в силу.
2. Сбросить DeltaFetch
Когда мы запускаем сканер в первый раз, он будет сканировать с нуля. Если его снова запустить, просканированный URL-адрес больше не будет сканироваться. Затем нам нужно добавить параметры при запуске, чтобы сообщить сканеру, что я хочу снова выполнить сканирование.
scrapy crawl name -a deltafetch_reset=1
3. Признаки успеха
Как определить, что deltafetch вступила в силу?
В скрытом каталоге .scrapy в корневом каталоге программы найдите каталог deltafetch, который сгенерирует файл базы данных в соответствии с именем_краулера.Это файл базы данных berlekeyDB, который записывает информацию об URL-адресах, которые были просканированы.
Упомянутый ранее параметр deltafetch_reset=1 предназначен для очистки соответствующего файла базы данных.
демо
Сначала запустите сканер без добавления параметров, дважды запустите программу и просканируйте данные с одного и того же URL-адреса.
После настройки deltefetch. Когда вы запустите его во второй раз, вам будет предложено игнорировать просканированный URL-адрес и остановить сканирование.
Если вы хотите повторно просканировать ранее просканированный URL-адрес, добавьте параметр deltafetch_reset=1 перед запуском.
основной исходный код
Класс DeltaFetch — это основной код.
def process_spider_output(self, response, result, spider):
for r in result:
if isinstance(r, Request):
key = self._get_key(r)
if key in self.db:
logger.info("Ignoring already visited: %s" % r)
if self.stats:
self.stats.inc_value('deltafetch/skipped', spider=spider)
continue
elif isinstance(r, (BaseItem, dict)):
key = self._get_key(response.request)
self.db[key] = str(time.time())
if self.stats:
self.stats.inc_value('deltafetch/stored', spider=spider)
yield r
эпилог
Лично я считаю, что при установке deltafetch относительно легко столкнуться с проблемами, и нам все еще нужно проконсультироваться с дополнительной информацией. Следующая статья — scrapy-splash, подключаемый модуль для рендеринга веб-страниц, который может заменить селен.