Спарсить ссылки из пагинации с помощью Simple HTML DOM

257
02 июня 2017, 14:12

Добрый день. Нужно с сайта https://itp.ne.jp/genre_dir/9570/pg/1/?sr=1&ngr=1&num=20 вытащить все ссылки из пагинации, их там около 250, и записать в массив. Скрипт около минуты пытается что то выполнить, в итоге глохнет, ничего не выводит и ошибок тоже. Делаю на локалке, использую curl и Simple HTML DOM.

require_once('simple_html_dom.php');
function curl_get($url, $referer = 'https://www.google.ru/') {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_REFERER, $referer);
    $out = curl_exec($ch);  
    curl_close($ch);
    return $out;
}
function pagination_url() {
    static $i = 1;
    $current_url = array();
    $current_url[$i] = 'https://itp.ne.jp/genre_dir/9570/pg/'.$i.'/?sr=1&ngr=1&num=20';
    $html = curl_get($current_url[$i]);
    $dom = str_get_html($html);
    $current_li = $dom->find('.bottomNav ul li[class=current]', 0);
    $next_li = $current_li->next_sibling ();
    $next_url = $next_li->find('a', 0)->attr;
    if (!empty($next_url['href']) && isset($next_url['href'])) {
        $i++;
        pagination_url();
    }
    return $current_url;
}
echo '<pre>';
print_r(pagination_url());
echo '</pre>';
Answer 1

На сайте присутствует ограничение на число просматриваемых элементов, и ограничено оно значением в 5000. Рядом с пейджером указано число показанных записей и общее число элементов, например, 1-20件/37638件. То что в начале показаны номера текущих записей (1-20) вроде очевидно, судя по тому, что символ (в переводе item) присутствует в обоих частях, то означает он единицу измерения, т.е. штук. Можно изменить значение атрибута num в интервале 20-30 и на последней странице всегда будет число не превышающее 5000. Что подтверждает мысль об искусственном ограничении.

Так что на мой взгляд набор URL можно сгенерировать просто в цикле:

define('PAGE_COUNT', 250);
define('URL_PATTERN', "https://itp.ne.jp/genre_dir/9570/pg/[pnum]/?sr=1&ngr=1&num=20");
$urls = [];
for($pnum = 1; $pnum <= PAGE_COUNT; $pnum++){
    $urls[] = str_replace( '[pnum]', $pnum, URL_PATTERN);
}
print_r($urls);

Что касается вашего кода.

  • Скачивание страницы ресурсоемкая задача, и по времени и трафик гоняет. Время выполнения пхп-скрипта ограничено в php.ini. Можете увеличить, но качаться 250 страниц у вас будут долго.
  • На странице приведено сразу 10 ссылок, то есть количество скачиваний можно сократить в 10 раз, обработав все ссылки со страницы
  • Другим подходом будет сформировать несколько тестовых запросов на получение произвольной страницы. Например, 200. Если страница получена, то первые 200 ссылок можно формировать вручную. Это уменьшить количество скачиваний на этом интервале в 200 раз. В общем можно использовать метод деления отрезка пополам.
  • Ваша рекурсия весьма легко переделывается в цикл. По факту вы не используете всю суть рекурсии в этой функции (не используете данные полученные в предыдущем вызове функции). Использование рекурсии вместо цикла просто будет требовать все больше и больше ресурсов. Обычно такое приводит к StackOverflow или нехватки памяти.
  • Чтобы получить ссылку на следующую страницу не надо искать текущую в списке и брать следующую. В конце есть кнопка Следующая/Вперед/Далее 次へ.
  • Чтобы вытащить единственную нужную ссылку использование HTML DOM слишком трудозатратно. Эффективней найти нужный кусок текста и выдернуть ссылку с помощью регулярок или строковых функций.
READ ALSO
Каким образом применить LIKE в запросе

Каким образом применить LIKE в запросе

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

232
Диаграмма взаимодействия классов (PHP_UML)

Диаграмма взаимодействия классов (PHP_UML)

Привет! Не могу разобраться с PHP_UMLНикак не могу найти в интернете ответы на свои вопросы

273
Как сделать поиск по статичному сайту?

Как сделать поиск по статичному сайту?

Есть статичный старый сайт, с кучами страниц сделанных на htmlВопрос в том как реализовать более менее быстрый поиск? В какую сторону смотреть?...

275