Парсер сайта на PHP

Рассмотрим создание парсера на PHP с использованием языка запросов xPath.

Данные будут браться с одного популярного аниме-сайта (animevost.org). Нас будут интересовать следующие данные: название, год выхода, жанр, тип, количество серий, режиссер и описание. В результате использования xPath у нас отпадает необходимость в регулярных выражениях. Все это приятно отразится на скорости работы скрипта.

Листинг файла index.php.

<?php
set_time_limit(0);

libxml_use_internal_errors(true);

$start = microtime(true);

$url = 'http://animevost.org/zhanr/';
$refererUrl = 'http://animevost.org';
$nPagePause = 4;

$data = curlGetContents($url, $refererUrl);

if ($data['code'] == 200){

$doc = new DOMDocument();
$doc->loadHTML($data['data']);
$xPath = new DOMXpath($doc);

$startPage = 1;
$endPage = parseNumberLastPage($xPath);

echo 'Парсер начал работу...<br>';

while($startPage <= $endPage){
$link = "{$url}page/$startPage/";

$data = curlGetContents($link, $refererUrl);

if ($data['code'] == 200){
$doc = new DOMDocument();
$doc->loadHTML($data['data']);
$xPath = new DOMXpath($doc);

$data = [];

// Название
$d1 = parseContent($xPath, "//div[@id='dle-content']/div/div/h2/a");
// Год выпуска
$d2 = parseContent($xPath, "//div[@id='dle-content']/div[@class='shortstory']/div[@class='shortstoryContent']/table/tr/td/p", 'Год выхода:', 12);
// Жанр
$d3 = parseContent($xPath, "//div[@id='dle-content']/div[@class='shortstory']/div[@class='shortstoryContent']/table/tr/td/p", 'Жанр:', 6);
// Тип
$d4 = parseContent($xPath, "//div[@id='dle-content']/div[@class='shortstory']/div[@class='shortstoryContent']/table/tr/td/p", 'Тип:', 5);
// Количество серий
$d5 = parseContent($xPath, "//div[@id='dle-content']/div[@class='shortstory']/div[@class='shortstoryContent']/table/tr/td/p", 'Количество серий:', 18);

// Режиссёр
$d6 = parseGetProducer($xPath);

// Описание
$d7 = parseContent($xPath, "//div[@id='dle-content']/div[@class='shortstory']/div[@class='shortstoryContent']/table/tr/td/p", 'Описание:', 10);

// Массив для записи в файл
$c = count($d1);
for($i=0;$i<$c;$i++){
$data[] = implode('|', [$d1[$i], $d2[$i], $d3[$i], $d4[$i], $d5[$i], $d6[$i], $d7[$i]]);
}

unset($d1, $d2, $d3, $d4, $d5, $d6, $d7, $c);

file_put_contents('data/' . str_replace(['http:', 'https:', '//', '/', '.'], ['', '', '', '-', '_'], rtrim($link, '/')) . '.txt', implode("\n", $data));

// Каждую n-страницу делаем паузу в 3 сек.
if ($startPage % $nPagePause == 0){
sleep(3);
}

} else {
file_put_contents('data/errors.txt', date('d-m-Y H:i:s', time()) . ' Страница недоступна: ' . $data['errors'][0][1] . "\n", FILE_APPEND);
}

$startPage++;
}

echo 'Парсер завершил работу за ' . round(microtime(true) - $start, 1) . ' сек.<br>';

} else {
die('Что-то пошло не так');
}

/** Функции */

/**
* Прочесть содержимое файла в строку при помощи cUrl
*
* @param $pageUrl Ссылка-источник
* @param $baseUrl Ссылка referer
* @param int $pauseTime Пауза между запросами
* @param bool $retry Разрешить / не разрешить повторение
* @return mixed
*/
function curlGetContents($pageUrl, $baseUrl, $pauseTime = 4, $retry = true) {
$errors = [];

$ch = curl_init();

curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, getRandomUserAgent());

curl_setopt($ch, CURLOPT_URL, $pageUrl);
curl_setopt($ch, CURLOPT_REFERER, $baseUrl);

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

$response['data'] = curl_exec($ch);

$ci = curl_getinfo($ch);

if($ci['http_code'] != 200 && $ci['http_code'] != 404) {
$errors[] = [1, $pageUrl, $ci['http_code']];

if($retry) {
sleep($pauseTime);
$response['data'] = curl_exec($ch);
$ci = curl_getinfo($ch);

if($ci['http_code'] != 200 && $ci['http_code'] != 404){
$errors[] = [2, $pageUrl, $ci['http_code']];
}
}
}

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Добавить комментарий

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: