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

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

Логи при парсинге

Совет: ведите логи при парсинге. Создайте отдельную таблицу в базу данных, в которую парсер будет записывать все свои действия: "Зашел на такую-то страницу", "Начал парсить такую-то категорию" и так далее - любые действия парсера.

Это, конечно же, замедлит работу парсера, но не сильно существенно.

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

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

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

Еще совет: парсер лучше сразу начинать делать с логами, а не тогда, когда куча проблем заявит о себе - ведь тогда интегрировать логи будет гораздо сложнее и затратнее по времени.

Еще совет: автоматически очищайте таблицу с логами перед новым парсингом (sql команда TRUNCATE).

Кеш при парсинге

Когда вы будете разрабатывать парсер, с первого раза у вас ничего не получится и придется постоянно дергать сайт, который вы парсите.

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

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

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

Сохранение при обрыве

Если сайт, который вы парсите - достаточно большой и парсится достаточно много времени - может случится обрыв.

Причины: банальные проблемы с интернетом, или компьютер отключится, или вам срочно нужно отойти, а сайт еще не спарсился, или вас забанил сайт, который вы парсите.

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

Поэтому хотелось бы иметь возможность сохранения и возобновления парсинга с места обрыва.

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

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

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

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

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

Автоматический запуск парсера в браузере

TODO: ссылки на плагин для хрома.

Размещение парсера в интернете

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

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

Хостинг. Преимущества: удобно запускать периодический парсинг, можно купить несколько ip для обхода защиты от парсинга (может быть дороговато). Недостатки: платно, статичный ip легко могут забанить при парсинге.

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

Самостоятельное задание: погуглите VDS хостинги, попробуйте разместить там ваш скрипт.

Работа с cron

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

Если вы заведете себе VDS - в настройках вы обязательно увидите вкладку Cron, перейдя на которую вы сможете запускать скрипты по расписанию. Это несложно - залезьте в настройки - вы все увидите.

Предупреждение: не следует запускать кроном урлы своего сайта - вы легко можете подвесить свой сервер. Запускайте файлы своего скрипта.

Настройки PHP

Есть некоторые настройки PHP, необходимые при парсинге. Их следует вызывать в начале скрипта с парсером.

Команда ini_set('max_execution_time', '10000') устанавливает время выполнения скрипта PHP в секундах (по умолчанию оно очень мало - около минуты). Ставьте побольше.

Функция set_time_limit(0) отменяет ограничение на время выполнения скрипта. Используйте вместе с предыдущей командой.

Команда ini_set('memory_limit', '2048M') устанавливает лимит оперативной памяти, выделяемой на скрипт. Ставьте побольше.

Функция ignore_user_abort(true) делает так, чтобы даже если в браузере оборвут скрипт - он продолжался дальше. Значение false отменяет это это поведение.