Intereting Posts
Ошибка анализа: синтаксическая ошибка, неожиданный «public» (T_PUBLIC) Как получить агент пользователя в PHP Как отобразить ошибку, когда загруженные файлы превышают post_max_size php? Передайте возвращаемое значение из php в js Поиск похожих или похожих ключевых слов из String PHP Получить имя текущего файла в архиве Phar регулярное выражение для учета периодов после числового символа только в php Создание SubReport в iReport 5.6 не работает Изображение водяного знака в php PHP MySQL Выберите * из 2 разных таблиц и отобразите данные, смешанные вместе, упорядоченные по столбцу datetime в обеих таблицах масштабирование изображения пропорционально, не зная размеров Можно ли смешивать API MySQL в PHP? Как получить окончательный, перенаправленный, канонический URL-адрес веб-сайта с использованием PHP? MySQL, подсчитайте количество заполненных полей в таблице Как вы отправляете NULL как переменную от PHP к SQL?

Ошибки в отношении веб-сканера в PHP

Я пытаюсь создать простой веб-искатель с использованием PHP, который способен обходить домены .edu, при условии семенных URL-адресов родителя.

Я использовал простой html dom для реализации искателя, а часть основной логики реализована мной.

Я отправляю код ниже и попытаюсь объяснить проблемы.

private function initiateChildCrawler($parent_Url_Html) { global $CFG; static $foundLink; static $parentID; static $urlToCrawl_InstanceOfChildren; $forEachCount = 0; foreach($parent_Url_Html->getHTML()->find('a') as $foundLink) { $forEachCount++; if($forEachCount<500) { $foundLink->href = url_to_absolute($parent_Url_Html->getURL(), $foundLink->href); if($this->validateEduDomain($foundLink->href)) { //Implement else condition later on $parentID = $this->loadSaveInstance->parentExists_In_URL_DB_CRAWL($this->returnParentDomain($foundLink->href)); if($parentID != FALSE) { if($this->loadSaveInstance->checkUrlDuplication_In_URL_DB_CRAWL($foundLink->href) == FALSE) { $urlToCrawl_InstanceOfChildren = new urlToCrawl($foundLink->href); if($urlToCrawl_InstanceOfChildren->getSimpleDomSource($CFG->finalContext)!= FALSE) { $this->loadSaveInstance->url_db_html($urlToCrawl_InstanceOfChildren->getURL(), $urlToCrawl_InstanceOfChildren->getHTML()); $this->loadSaveInstance->saveCrawled_To_URL_DB_CRAWL(NULL, $foundLink->href, "crawled", $parentID); /*if($recursiveCount<1) { $this->initiateChildCrawler($urlToCrawl_InstanceOfChildren); }*/ } } } } } } } 

Теперь, когда вы можете видеть, что initiateChildCrawler вызывается функцией initiateParentCrawler, которая передает родительскую ссылку дочернему искателю. Пример родительской ссылки: www.berkeley.edu, для которой искатель найдет все ссылки на главной странице и вернет все содержимое html. Это происходит до тех пор, пока семя не исчерпается.

например: 1-harvard.edu – >>>>> найдет все ссылки и вернет их содержимое html (путем вызова childCrawler). Переход к следующему родительскому элементу в parentCrawler. 2-berkeley.edu – >>>>> Вы найдете все ссылки и вернете свой html-контент (путем вызова childCrawler).

Другие функции самоочевидны.

Теперь проблема: после того, как childCrawler завершит цикл foreach для каждой ссылки, функция не сможет выйти из строя. Если я запускаю скрипт из CLI, CLI падает. При запуске скрипта в браузере завершается сценарий.

Но если я установил предел обхода дочерних ссылок на 10 или что-то меньшее (изменив переменную $ forEachCount), искатель начнет нормально работать.

Пожалуйста, помогите мне в этом.

Сообщение от CLI:

Подпись задачи: Проблема Имя события: APPCRASH Имя приложения: php-cgi.exe Версия приложения: 5.3.8.0 Временная метка приложения: 4e537939 Имя модуля неисправности: модуль ошибки php5ts.dll Версия: 5.3.8.0 Модуль сбоя Временная метка: 4e537a04 Код исключения: c0000005 Исключение Смещение: 0000c793 Версия ОС: 6.1.7601.2.1.0.256.48 Locale ID: 1033 Дополнительная информация 1: 0a9e Дополнительная информация 2: 0a9e372d3b4ad19135b953a78882e789 Дополнительная информация 3: 0a9e Дополнительная информация 4: 0a9e372d3b4ad19135b953a78882e789

Пример плоской петли:

  1. Вы инициируете цикл со стеком, который содержит все URL-адреса, которые вы хотите обработать первым.
  2. Внутри цикла:
    1. Вы переносите первый URL-адрес (вы его получаете и удаляете) из стека.
    2. Если вы найдете новые URL-адреса, вы добавляете их в конец стека ( push ).

Это будет выполняться до тех пор, пока все URL-адреса из стека не будут обработаны, поэтому вы добавите (как уже есть для foreach ) счетчик, чтобы предотвратить слишком длительное выполнение:

 $URLStack = (array) $parent_Url_Html->getHTML()->find('a'); $URLProcessedCount = 0; while ($URLProcessedCount++ < 500) # this can run endless, so this saves us from processing too many URLs { $url = array_shift($URLStack); if (!$url) break; # exit if the stack is empty # process URL # for each new URL: $URLStack[] = $newURL; } 

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

 while ($URLProcessedCount < 500) # this can run endless, so this saves us from processing too many URLs { $url = $URLStack[$URLProcessedCount++]; 

Кроме того, я предлагаю вам использовать расширение PHP DOMDocument вместо простого dom, поскольку это гораздо более универсальный инструмент.