#php #mysql #performance #web-crawler
#php #mysql #Производительность #веб-сканер
Вопрос:
В настоящее время я пытаюсь сканировать много данных с веб-сайта, однако я немного борюсь с этим. Он имеет индекс от а до Я и индекс 1-20, поэтому в нем есть куча циклов и DOM. Тем не менее, ему удалось выполнить сканирование и сохранить около 10 000 строк при первом запуске, но сейчас у меня около 15 000, и он сканирует только около 100 за один запуск.
Вероятно, это связано с тем, что он должен пропускать строки, которые он уже вставил (сделал проверку для этого). Я не могу придумать способ легко пропустить некоторые страницы, так как индекс 1-20 сильно варьируется (для одного письма есть 18 страниц, другое письмо — всего 2 страницы).
Я проверял, была ли уже запись с заданным идентификатором, если нет, вставьте ее. Я предполагал, что это будет медленно, поэтому теперь перед запуском скрипта я извлекаю все строки, а затем проверяю с помощью in_array(), предполагая, что это быстрее. Но это просто не сработает.
Итак, мой поисковый робот просматривает 26 букв, по 20 страниц на каждую букву, а затем до 50 раз на каждой странице, так что, если вы посчитаете это, это много.
Думал запустить его по буквам, но это не сработает, так как я все еще застрял на «a» и не могу просто перейти на «b», так как я буду пропускать записи из «a».
Надеюсь, я объяснил проблему достаточно хорошо, чтобы кто-то мог мне помочь. Мой код выглядит примерно так: (я удалил некоторые вещи здесь и там, думаю, все важные вещи здесь, чтобы дать вам представление)
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) amp;amp; in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
/* CONNECT TO DB */
mysql_connect()......
$qry = mysql_query("SELECT uid FROM tableName");
$all = array();
while ($row = mysql_fetch_array($qru)) {
$all[] = $row;
} // Retrieving all the current database rows to compare later
foreach (range("a", "z") as $key) {
for ($i = 1; $i < 20; $i ) {
$dom = new DomDocument();
$dom->loadHTMLFile("http://www.crawleddomain.com/".$i."/".$key.".htm");
$finder = new DomXPath($dom);
$classname="table-striped";
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
foreach ($nodes as $node) {
$rows = $finder->query("//a[contains(@href, '/value')]", $node);
foreach ($rows as $row) {
$url = $row->getAttribute("href");
$dom2 = new DomDocument();
$dom2->loadHTMLFile("http://www.crawleddomain.com".$url);
$finder2 = new DomXPath($dom2);
$classname2="table-striped";
$nodes2 = $finder2->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname2 ')]");
foreach ($nodes2 as $node2) {
$rows2 = $finder2->query("//a[contains(@href, '/loremipsum')]", $node2);
foreach ($rows2 as $row2) {
$dom3 = new DomDocument();
//
// not so important variable declarations..
//
$dom3->loadHTMLFile("http://www.crawleddomain.com".$url);
$finder3 = new DomXPath($dom3);
//2 $finder3->query() right here
$query231 = mysql_query("SELECT id FROM tableName WHERE uid='$uid'");
$result = mysql_fetch_assoc($query231);
//Doing this to get category ID from another table, to insert with this row..
$id = $result['id'];
if (!in_array_r($uid, $all)) { // if not exist
mysql_query("INSERT INTO')"); // insert the whole bunch
}
}
}
}
}
}
}
Комментарии:
1. Где это
$uid
определено?2. Создайте уникальный индекс
uid
, а затем выполните вставки в db сINSERT ON DUPLICATE KEY IGNORE
помощью let db, чтобы выполнить тяжелую работу.3. Я не могу использовать это, поскольку uid может быть таким же, поскольку заголовок может существовать в других категориях. Я не могу их объединить, так как это совершенно разные статьи, но с одним и тем же именем. Нашел это решение, но это не решение для меня, слишком плохо…
Ответ №1:
$uid
не определено, кроме того, этот запрос не имеет смысла:
mysql_query("INSERT INTO')");
Вы должны включить сообщение об ошибках:
ini_set('display_errors',1);
error_reporting(E_ALL);
После ваших запросов вы должны выполнить or die(mysql_error());
Кроме того, я мог бы также сказать это, если я этого не сделаю, кто-то другой. Не используйте mysql_*
функции. Они устарели и будут удалены из будущих версий PHP. Попробуйте PDO.
Комментарии:
1. Как я уже сказал, я удалил такие вещи, как бесполезные объявления переменных, и сократил некоторые запросы. Все они работают и не повреждены. Поскольку это должно делать все с количеством запросов и сканированием, я подумал, что хранить весь код бесполезно. Не волнуйтесь, пути работают, и все переменные определены.
2. Хорошо, но все же
INSERT INTO')
это неправильный запрос.3. @Adelphia Он удалил некоторый код, чтобы создать небольшой пример.
4. @ArkoElsenaar вы должны обновить свой вопрос своим самым последним кодом, если хотите получить полезный ответ, вы знаете? 😉
5. @ArkoElsenaar возможно, вы правы, но опять же: если это не имеет значения, зачем нам вообще тратить эти минуты на чтение вашего вопроса? Такое отношение просто неправильно по отношению к тому, кто пытается вам помочь.