Добавлю то, о чём ещё не упоминали.
Вот как бы сама архитектура "на пальцах":
0-[Командуем: url task manager: queue]
1-1234567890 [льём: head-less browser/etc.]
2-1234567890 [decomposer]
3-123456...
....
N-1234567890 [сохраняем: db data insert]
Goto 0
Строки - уровни обработки, числа - параллельные единичные потоки.
1. Задача - динамическая коммутация между функциональными потоками соседних слоёв.
Т.е. поток после отработки никогда не закрывается, а ждёт нового задания от любого блока с уровня выше (меньший номер строки)!
В этом - вся "соль" скорости обработки!
2. Копите знания: Всегда кэшируйте "скелет" нахождения данных (динамические правила) при интеллектуальной декомпозиции разметки - это сильно сокращает время детекции уже встречавшихся блоков (одинаковый блок кода или шаблон страницы, одинаковая CMS, и т.д.).