Форум программистов, компьютерный форум, киберфорум
Наши страницы
PHP для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/12: Рейтинг темы: голосов - 12, средняя оценка - 4.75
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
1

Парсинг данных из xml файла в определенное время с частичным выводом на сайт

07.07.2014, 11:23. Просмотров 2401. Ответов 17
Метки нет (Все метки)

Добрый день, уважаемые жители форума.
Прошу помощи, так как не знаю как подступиться к выполнению следующей задачи, необходимо ежедневно в определенное время, а именно в 23-30 обратиться к файлу находящемуся вот тут: http://img.ignio.com/r/export/utf/xml/daily/com.xml
далее этот файл сохранить на собственном сайте и разобрать его на данные, для последующего вывода на различных станицах сайта, а именно гороскопов для определенного знака зодиака на определенную дату.
На текущий момент это реализовано не автоматически, просто создаю руками файл с построчными данными на каждый знак зодиака и вывожу с помощью:
PHP
1
2
3
4
5
6
<?
  $file_array = file("http://personaastro.ru/goroskop.txt");
  
printf("%s<br>", $file_array[2]);
 
?>
но это ужасно не удобно и отнимает время, так же был некоторое время назад реализован парсер с непосредственным обращением к другому сайту:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
 
 
$data = file_get_contents('http://www.taishet.ru/horoscope/');
$data = iconv('cp1251', 'utf-8', $data); // уберите эту строчку, если не используете utf-8
preg_match_all('#<br><br><b>([^<]*+)</b><br>(?>(.*?)(?=<br><br>))#sS', $data, $matches, PREG_SET_ORDER);
//print_r($matches); -- раскоментируйте, чтобы узнать что получилось в массиве
$nl = PHP_SAPI === 'cli' ? "\n" : '<br>'; // это нафиг уберите когда на сервере запускать будете.
//print_r($matches[2]);
/*
в массиве $matches записаны зодиаки
$matches[2] //близнецы
$matches[2][1]// Название
$matches[2][2]// Описание
*/
// echo $matches[2][1];
echo "<br/>" . $matches[0][2];
?>
Но данный ресурс очень не надежен и от такой схемы я отказался, разместить все необходимо на вот этом сайте: http://personaastro.ru/

Заранее благодарен.
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.07.2014, 11:23
Ответы с готовыми решениями:

Чтение Xml файла с выводом данных в DataGridView
Возможно ли, зная структуру файла xml вывести данные в DataGridView? очень прошу помощи!...

Парсинг XML с выводом в AJAX
Всем привет! Нужно из файла XML извлечь данные (картинки, описание погоды, температуру) в отдельные...

Парсинг сайта через определенное время
Каким образом реализовать парсинг страницы через, допустим полчаса?

Отсчитывать определенное время с момента захода посетителя на сайт
Приветствую, форумчане, давненько не виделись ;) Срочно ищу скрипт обратного отсчета для сайта. ...

Парсинг XML-файла с помощью LINQ to XML
Здрасивуйте. Трабл никак не могу понять в чем дело не могу считать инфу с XML login, getWorkersOUs...

17
BarbosLV
363 / 401 / 165
Регистрация: 29.05.2014
Сообщений: 1,494
07.07.2014, 12:31 2
Ну так можно сразу парсить с сети:
PHP
1
2
3
4
5
6
7
8
$xml = @simplexml_load_file("http://img.ignio.com/r/export/utf/xml/daily/com.xml") or die("Оракул не в сети :D");
$yesterday = $xml->date['yesterday'];
$today = $xml->date['today'];
$tomorrow = $xml->date['tomorrow'];
echo "<h3>Овен:</h3>";
echo "<b>$yesterday</b> -".$xml->aries->yesterday."<br><br>";
echo "<b>$today</b> -".$xml->aries->today."<br><br>";
echo "<b>$tomorrow</b> -".$xml->aries->tomorrow."<br><br>";
1
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
07.07.2014, 12:55  [ТС] 3
Цитата Сообщение от BarbosLV Посмотреть сообщение
Ну так можно сразу парсить с сети
Согласен, только есть одно но, на сайте доноре, жесткое условие по обращению с данному файлу не чаще одного раза в час, а у меня может за час до 50 обращений в таком случае быть.
Именно по этому хочу реализовать одно обращение в течении суток и запись данных в другой файл, с последующим обращением к нему.
0
BarbosLV
363 / 401 / 165
Регистрация: 29.05.2014
Сообщений: 1,494
07.07.2014, 13:02 4
Ну так а что мешает предварительно скопировать на сайт?
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
$file = 'http://img.ignio.com/r/export/utf/xml/daieely/com.xml';
$newfile = "xml/orakul.xml";
if (!copy($file, $newfile)) {
    echo "Если не удалось скопировать ($file) ...\n";
}
$xml = @simplexml_load_file("xml/orakul.xml") or die("Оракул не в сети :D");

Ну и добавь условие если сегодня уже копировал то не повторять операцию.
2
07.07.2014, 13:02
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
07.07.2014, 14:18  [ТС] 5
BarbosLV, Спасибо, т.е. нужно добавить проверку функцией filemtime с ткущей датой?
0
Tatikoma
F́́́́́́́ŕ́́́́́́́é́́́ ́ak
259 / 223 / 109
Регистрация: 07.07.2014
Сообщений: 965
07.07.2014, 14:21 6
BarbosLV, копировать файлы по http с помощью функции copy, - как минимум, моветон.

ili, задача замечательно разбивается на три маленькие подзадачки решение которых прекрасно гуглится:
1. Нужен скрипт который будет загружать файл и сохранять локально.
2. Нужно чтобы скрипт из пункта 1 запускался каждый день в 23:30 (сомнительно, не лучше ли раз в два часа, на случай если не удалось загрузить файл?).
3. Нужно поправить код отображения для работы с локальным файлом.

Соответственно по-пунктам:
1.
PHP
1
2
3
4
5
6
7
8
<?php
$fp = fopen('/путь/куда/сохранить/полученный/файл/oracle.xml', 'w+'); // не забываем убедится что в системе установлены права на запись файла
$ch = curl_init("http://img.ignio.com/r/export/utf/xml/daily/com.xml");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
2. Для *nix систем есть планировщик задач cron: заходим на сервер по ssh, вводим "crontab -e" для редактирования правил планировщика и сохраняем следующую строчку:
Код
30 23 * * * cd /путь/к/файлу/скрипта/ && php имя_скрипта.php 2>&1 >> /var/log/что-нибудь.log
Последняя часть записи - перенаправление stderr в stdout + последующее перенаправление stdout в файл. Если что-то пошло не так - всегда можно будет прочитать что скрипт вывел на экран в файле логов.
Для запуска раз в два часа строчка в crontab может выглядеть так:
Код
30 */2 * * * cd /путь/к/файлу/скрипта/ && php имя_скрипта.php 2>&1 >> /var/log/что-нибудь.log
3. Непосредственно поправить скрипт на работу с локальным файлом, с этим кажется проблем быть не должно + в теме уже рассмотрено.
0
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
07.07.2014, 15:00  [ТС] 7
Tatikoma, спасибо, буду реализовывать данным способом, о результатах отпишусь.
0
BarbosLV
363 / 401 / 165
Регистрация: 29.05.2014
Сообщений: 1,494
07.07.2014, 15:01 8
Цитата Сообщение от Tatikoma Посмотреть сообщение
BarbosLV, копировать файлы по http с помощью функции copy, - как минимум, моветон.
Ну и какие же недостатки у этой функции? Я лично, вижу только нотис, но его можно заглушить @copy().

Цитата Сообщение от ili Посмотреть сообщение
т.е. нужно добавить проверку функцией filemtime с ткущей датой?
Да можно и так. Вариантов то с десяток. Выбирай какой для тебя проще.
1
Tatikoma
F́́́́́́́ŕ́́́́́́́é́́́ ́ak
259 / 223 / 109
Регистрация: 07.07.2014
Сообщений: 965
07.07.2014, 15:28 9
ili, небольшая поправочка по-первому пункту, нужно корректно обрабатывать ситуацию, если не удалось загрузить файл + не стирать файл, пока новый не загружен. Иначе во время загрузки файла у пользователей будут возникать вполне понятные проблемы.. =)

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$path = '/путь/куда/сохранить/полученный/файл/';
$fp = fopen($path. 'oracle.tmp', 'w+'); // не забываем убедится что в системе установлены права на запись файла
$ch = curl_init("http://img.ignio.com/r/export/utf/xml/daily/com.xml");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if(curl_exec($ch)){
  // ok, файл загружен, заменяем
  rename($path.'oracle.tmp', $path.'oracle.xml');
}
else{
  echo strtr("Во время загрузки файла произошли ошибки :error\r\n", array(
    ':error' => curl_error($ch),
  ));
}
curl_close($ch);
fclose($fp);
BarbosLV, самый главный недостаток в том, что этом - моветон. Так же есть придирки:
1. Глушить вывод ошибок относительно дорогая операция. Дело в том, что символ собачки на время выполнения следующих за ним операторов - переключает настройку вывода ошибок (так же как это делал бы ini_set('error_reporting', E_NONE)). Кроме того, вы действительно считаете, что разработчики PHP глупее вас, раз выводят ошибку на такой хороший и правильный код?
2. Каждому инструменту - свое место. Обычно люди пытаются забивать гвозди микроскопом, а тут скорее попытка рассмотреть бактерии на молотке..
3. Поддерживаемость кода. Если судить по себе, то лично я когда вижу функцию copy - скорее думаю о копировании одного локального файла в другой локальный файл. С загрузкой файла по http - это слабо ассоциируется, это может затруднить работу с кодом другими программистами.

Не холивара ради, но рассмотрим гипотетическую ситуацию с тем, - прошло десять лет, целевой сайт жив здоров, но полностью перешел на HTTP/2.0 (который, напоминаю, бинарный как, например, SPDY который уже довольно популярен). Как по-вашему будет развиваться ситуация при использовании функции copy и при использовании библиотеки curl? ;-)

--------------

Сразу не обратил внимания, выше был предложен вариант при запросе страницы с предсказаниями - смотреть дату файла и, если он устарел, - скачивать свежую версию, после чего отображать результат. Здесь так же есть подводные камни, которые почему-то советчиком проигнорированы:
1. Загрузка файла может занять длительное время, например из-за повышенной нагрузки на удаленном сервере. Соответственно пользователь будет ждать пока файл загрузится, что не очень хорошо.
2. Загрузка файла может завершится с ошибкой, эту ситуацию нужно корректно обрабатывать, а не выводить пользователю что вы не смогли скачать файлик.
3. На страницу может зайти сразу несколько пользователей, что повлечет за собой несколько запросов на скачивание файла, что приводит к плохим последствиям.
4. В случае DDoS-атаки на сайт, - этот скрипт будет резко бросаться в глаза из-за повышенного времени ответа связанного с сетевыми задержками. Положить такой сайт можно будет легко с пары десятков телефонов на мобильном интернете (при условии использования "обычного" хостинга)... Про серьезные ботнеты и говорить не приходится.
0
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
08.07.2014, 01:07  [ТС] 10
Tatikoma, пытаюсь записать данные по предложенному скрипту, создал файл getgoro.php, расположил по адресу: http://personaastro.ru/getgoro.php, при выполнении скрипта выводит на экран все правильно, но сам файл oracle.xml не перезаписывает, в чем проблема?
скрипт вот в таком виде:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$path = 'http://personaastro.ru/oracle.xml';
$fp = fopen($path. 'oracle.tmp', 'w+'); // не забываем убедится что в системе установлены права на запись файла
$ch = curl_init("http://img.ignio.com/r/export/utf/xml/daily/com.xml");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if(curl_exec($ch)){
  // ok, файл загружен, заменяем
  rename($path.'oracle.tmp', $path.'oracle.xml');
}
else{
  echo strtr("Во время загрузки файла произошли ошибки :error\r\n", array(
    ':error' => curl_error($ch),
  ));
}
curl_close($ch);
fclose($fp);
?>
0
Tatikoma
F́́́́́́́ŕ́́́́́́́é́́́ ́ak
259 / 223 / 109
Регистрация: 07.07.2014
Сообщений: 965
08.07.2014, 01:10 11
Цитата Сообщение от ili Посмотреть сообщение
$path = 'http://personaastro.ru/oracle.xml';
Цитата Сообщение от Tatikoma Посмотреть сообщение
$path = '/путь/куда/сохранить/полученный/файл/';
Нужно указать не URL-адрес, а путь к папке на сервере. Например: "/var/www/mysite/ugc/" или "C:\\www\\mysite\\ugc\\". При этом нужно убедится, что папка по указанному пути существует и доступна для записи пользователем, от имени которого запускается скрипт.

Ну или напишите просто:
PHP
1
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR;
если хотите складировать в папку рядом со скриптом.
0
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
08.07.2014, 01:39  [ТС] 12
Tatikoma, спасибо, заменил строку, доступ разрешил, сохранение работает, теперь проблема с выводом части текста, создал тестовую страницу http://personaastro.ru/goroskop_na_segodnya_bliznetsy1.html которая на данный момент выдает ошибку 500, в ней следующий код:
PHP
1
2
3
4
5
6
7
8
9
<?php
 
$xml = @simplexml_load_file("http://personaastro.ru/oracle.xml");
$yesterday = $xml->date['yesterday'];
$today = $xml->date['today'];
$tomorrow = $xml->date['tomorrow'];
echo .$xml->gemini->today."<br><br>";
 
?>
Что тут я не правильно сделал?
0
Tatikoma
F́́́́́́́ŕ́́́́́́́é́́́ ́ak
259 / 223 / 109
Регистрация: 07.07.2014
Сообщений: 965
08.07.2014, 01:41 13
Цитата Сообщение от ili Посмотреть сообщение
$xml = @simplexml_load_file("http://personaastro.ru/oracle.xml");
Не используйте HTTP. Вы же уже скачали файл - зачем вы его опять качаете!? Пишите локальный путь к файлу, как только что научились это делать в скрипте загрузки.

А почему не работает - не ясно, добавьте вывод ошибок:
PHP
1
2
error_reporting(E_ALL);
ini_set('display_errors', 'on');
0
BarbosLV
363 / 401 / 165
Регистрация: 29.05.2014
Сообщений: 1,494
08.07.2014, 01:53 14
Лишняя точка
echo .$xml->gemini->today."<br><br>";
0
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
08.07.2014, 01:55  [ТС] 15
сделал вот так:
PHP
1
2
3
4
5
6
7
8
9
<?php
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR;
$xml = @simplexml_load_file("$path. /oracle.xml");
$yesterday = $xml->date['yesterday'];
$today = $xml->date['today'];
$tomorrow = $xml->date['tomorrow'];
echo .$xml->gemini->today."<br><br>";
 
?>
посмотрел по логам, ругается на 226 строку, т.е. на
PHP
1
echo .$xml->gemini->today."<br><br>";
Добавлено через 1 минуту
BarbosLV, спасибо, убрал, ошибка пропала, но информацию не выводит, текста нет на странице.
0
BarbosLV
363 / 401 / 165
Регистрация: 29.05.2014
Сообщений: 1,494
08.07.2014, 01:57 16
Ну я теперь уже и не знаю что тебе там понасоветовали и что за код в итоге вышел. Собаку кстати можешь убрать, она нужна была только в первой редакции кода)))
0
Tatikoma
F́́́́́́́ŕ́́́́́́́é́́́ ́ak
259 / 223 / 109
Регистрация: 07.07.2014
Сообщений: 965
08.07.2014, 01:58 17
Лучший ответ Сообщение было отмечено ili как решение

Решение

PHP
1
2
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR;
$xml = @simplexml_load_file("$path. /oracle.xml"); // тут ошибка, у вас получается путь вида "/var/www/mysite/. /oracle.xml"
Правильно так:
PHP
1
2
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR;
$xml = simplexml_load_file("{$path}oracle.xml");
0
ili
0 / 0 / 0
Регистрация: 14.03.2013
Сообщений: 22
08.07.2014, 02:06  [ТС] 18
Tatikoma, супер, теперь все работает, осталось правильно настроить автозагрузку каждые два часа, я посмотрел у меня на хостинге предустановлена эта опция, спасибо огромное за помощь всем участникам.
0
08.07.2014, 02:06
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2014, 02:06

Запуск файла в определенное время
procedure TForm1.Timer1Timer(Sender: TObject); var T:TDateTime; begin T:=time; ...

Экспорт данных в определенное время
Сново появилась проблема для решения которой необходима помощь знающих людей. Нужно, чтобы каждые...

Удаление данных на определенное время
Подскажите,как удалить данные из таблицы на определенное время( Например если 1 номер в гостиннице...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru