copysite

Те, кто хоть раз писал парсер, знает, что не стоит этого делать с помощью регулярных выражений. Проиллюстрировать это утверждение поможет следующий пример.

 Возьмем HTML код: 

<div><a href="http://xdan.ru"><div>Сайт по программированию парсеров</div><div> и многое другое</div></a></div>

К примеру, из него нам нужно получить описание и url сайта. Если брать исключительно этот кусок кода, то все решается достаточно просто: 

$html = '<div><a href="http://xdan.ru"><div>Сайт по программированию парсеров</div><div> и многое другое</div></a></div>';
preg_match('#<div><a href="([^"]+)"><div>([^<]+)</div><div>([^<]+)</div></a></div>#U',$html,$list);
echo 'url:'.$list[1].',title:'.$list[2].$list[3]; // выведет url:http://xdan.ru,title:Сайт по программированию парсеров и многое другое

Проблемы начинаются тогда, когда описание сайта заполняют пользователи, и оно не имеет   определенного шаблона.

<div><a href=”http://xdan.ru”><div>Сайт по <b>программированию</b> парсеров</div><div> и многое <div> многое </div> другое </div></a></div>

Такой код регулярному выражению не по зубам.

Обычно, в вузах на этот случай учат писать конечный автомат. Суть его в том, что мы перебираем, посимвольно, весь html текст, находим начало тега, и строим дерево документа. Так называемое DOM (Document Object Model)

Сейчас, писать такое самому  нет необходимости.

В php, начиная с  версии 5, есть встроенные методы работы с деревом документа (класс DOMDocument), но основан он на XML парсере.

А HTML и XML это хоть и очень похожие, но в тоже время абсолютно разные технологии.

К примеру, непременное требование к XML это закрытые теги и отсутствие ошибок.

Отсюда вытекает условие: ошибок в html, который мы парсим с помощью нативных средств php,  быть не должно.

К сожалению, на сайтах донорах, ошибки не редки, а значит этот метод отпадает.

Для корректного разбора таких сайтов, на помощь придут php библиотеки PHPQuery, Simple HTML DOM, Zend DOM Query, Nokogiri .

Некоторые из них, после небольших манипуляций скармливают html  тому же DOMDocument. Мы не будем их рассматривать.

В этой статье я расскажу про SimpleHTMLDOM. Этой библиотекой я пользуюсь уже несколько лет, и она меня еще ни разу не подводила.

Скачиваем последнюю версию здесь

Пусть Вас не смущает то, что она не обновлялась с 2008 года, то, что она умеет, полностью покроет Ваши нужды в разборе html текстов.

В архиве, который вы скачали, две папки (примеры работы и документация) и файл simple_html_dom.php.

simple_html_dom.php это и есть вся библиотека, больше ничего для работы не потребуется. Кидаем этот файл в папку с проектом и в своем скрипте просто подгружаем его.

include 'simple_html_dom.php';

Кроме документации, которую вы скачали с архивом, доступна еще online версия, ее  вы найдете здесь

Файл подключен и готов к работе.

Для того, чтобы начать разбирать HTML, его сперва нужно получить. Обычно, я делаю это при помощи библиотеки CURL.

В simplehtmldom есть методы для удаленной загрузки страниц.  После подключения файла библиотеки, нам доступны 2 функции для обработки HTML строк.

str_get_html(str) и file_get_html(url)

Они  делают одно и тоже, преобразуют HTML текст в DOM дерево, различаются лишь источники.

str_get_htm – на вход получает обычную строку, т.е. если вы получили HTML прибегнув к curl, или file_get_contents то вы просто передаете полученный текст этой функции.

$html = str_get_html('<html><body>Привет!</body></html>');

file_get_html – сама умеет загружать данные с удаленного URL или из локального файла

$html = file_get_html('http://www.yandex.ru/');

или

$html = file_get_html('data/test.htm');

К сожалению,  file_get_html загружает страницы обычным file_get_contents. Это значит если хостер, выставил в php.ini allow_url_fopen = false (т.е. запретил удаленно открывать файлы), то загрузить что-то удаленно, не получится. Да и серьезные веб сайты таким способом парсить не стоит, лучше использовать CURL с поддержкой proxy и ssl. Однако для наших опытов, вполне хватит и file_get_html.

$html = file_get_html('http://www.yandex.ru/'); 

в результате, в  переменной $html будет объект типа simple_html_dom.

При больших объемах данных, в библиотеке происходит утечка памяти. Поэтому после окончания одного цикла надо ее чистить.

Делает это метод clear.

К примеру грузим 5 раз сайт www.yandex.ru с разными поисковыми запросами

$k = 5; 
while($k>0){
 $html = file_get_html('http://yandex.ru/yandsearch?text=hi'.$k.'&lr=11114'); // загружаем данные
 // как-то их обрабатываем
 $html->clear(); // подчищаем за собой
 unset($html);
 $k--;
}

Эти две строчки $html->clear();  и unset($html);  лучше писать сразу же после того, как  Вы создали объект. Иначе забудете, и скрипт отвалится, забив всю память.

После того, как html текст упакован в объект, можно приступать непосредственно к поиску нужных элементов. 

Большинство поисковых функций выполняет метод find(selector, [index]).  Если второй аргумент не задан, метод возвращает массив элементов. Если же задан то элемент этого массива с индексом index.

Пример: скачаем главную страницу моего блога, и выведем все ссылки, которые встретим на своем пути.

require_once 'simple_html_dom.php';
$data = file_get_html('http://xdan.ru');
if($data->innertext!='' and count($data->find('a'))){
	foreach($data->find('a') as $a){
		echo '<a href="http://xdan.ru/'.$a->href.'">'.$a->plaintext.'</a></br>';
	}
}

В примере, в качестве селектора я воспользовался названием тега <a>. Но можно использовать и другие CSS селекторы. Элемент на странице можно найти по его атрибутам. В первую очередь, это название тега, id и class. Также могут быть использованы и второстепенные атрибуты, к примеру, href ссылки или width картинки. Если и этих атрибутов нет, то не грех воспользоваться и регулярными выражениями.

Поиск по названию тега вы уже видели

$html->find('div')

поиск по id

$html->find('#preview')

поиск по классу

$html->find('.myclass')

или комбинированный вариант

$html->find('#preview div.myclass')

в данном случае, сначала найдется элемент с id= preview затем в нем найдутся все теги div, и уже среди них фильтруются те у которых class=”myclass”

Если метод find ничего не нашел и index не задан, то он возвращает пустой массив. Если же index задан, то метод возвращает null.  

Поэтому верным решением будет проверить

if(count($html->find('#preview div.myclass')))
	foreach($html->find('#preview div.myclass') as $div)
		echo $div->innertext;

Поиск по наличию атрибута

$html->find(' img [width]'); // найдет нам все изображения у которых задан атрибут ширина

или более конкретный поиск по значению атрибута

$ret = $html->find('img[width=400px]');// найдет все изображения, у которых задана ширина равная 400px

Такая нотация позволяет искать по двум и более смежным классам

$ret = $html->find('img[class=active myclass]');//<img class="active myclass"/>

Поиск нескольких тегов

$html->find('a, img, br,span');

Поиск вложенных тегов

$es = $html->find('ul.myclass li');// найдет все li который является потомком ul(возможно и не прямым)
$es = $html->find('div.myclass li');// найдет все li в  div.myclass

У каждого найденного элемента также есть метод find

$html->find('div.myclass li');//найдет все div.myclass а потом все li лежащие в них

если нам нужно найти все li только первого div’а то мы можем написать так

$html->find('div.myclass',0)->find('li');

Поиск по значению атрибута не ограничивается только равенством. Вот доступные условия

[атрибут] – проверяет есть ли у элемента данный атрибут

[атрибут=величина] - проверяет, есть ли у элемента данный атрибут и равно ли его значение величине.( div[class=myclass] – найдет все div’ы у которых class равен myclass)

[атрибут!=величина] - проверяет, есть ли у элемента данный атрибут и не равно ли его значение величине.( div[class!=myclassok] – найдет все div’ы у которых class не равен myclassok)

[атрибут^=величина] - проверяет, есть ли у элемента данный атрибут и начинается ли его значение с величины ( div[class^=my] – найдет все div’ы у которых class начинается с my, к примеру myclass и myclassok)

 [атрибут$=величина] - проверяет, есть ли у элемента данный атрибут и заканчивается ли его значение величиной( div[class$=ok] – найдет все div’ы у которых class заканчивается на ok, к примеру myclassok, yok, okно не oki)

 [атрибут*=величина] - проверяет, есть ли у элемента данный атрибут и содержит ли его значение в себе величину, в любом месте(div[class*=sok] – найдет все div’ы у которых class содержит sok, к примеру myclassok, ysoki, sok)

Обычный текст можно искать как тег text

$es = $html->find('text'); // найдет все текстовые блоки в html

Комментарии находим по тегу comment

$es = $html->find('comment');

Каждый найденный элемент и сам $html имеют 5 полей

$html = str_get_html("<div>foo <b>bar</b></div>"); 
echo $html; // выведет <div>foo <b>bar</b></div>;
$e = $html->find("div", 0);
echo $e->tag; // Вернет: "div"
echo $e->outertext; // Вернет: <div>foo <b>bar</b></div>
echo $e->innertext; // Вернет: foo <b>bar</b>
echo $e->plaintext; // Вернет: foo bar

$e->tag            Читает или записывает имя тега элемента.

$e->outertext   Читает или записывает весь HTML элемента, включая его самого.

$e->innertext   Читает или записывает внутренний HTML элемента

$e->plaintext    Читает или записывает простой текст элемента, это эквивалентно функции strip_tags($e->innertext). Хотя поле доступно для записи, запись в него ничего не даст, и исходный html не изменит

$html = str_get_html("<div>foo <b>bar</b></div"); 
$div = $html->find('div',0);
$div->plaintext = 'gooo';
echo $div->innertext; // вернет <div>foo <b>bar</b></div>

Как  Вы могли догадаться, для удаления ненужного элемента из HTML можно затереть его поле  outertext

$html = str_get_html("<div>foo <b>bar</b></div"); 
$b = $html->find('b',0);
$b->outertext = '';
echo $html->innertext; // вернет <div>foo</div>

Тут следует помнить, что хоть элемент и не виден в html, из дерева DOM он никуда не делся

$html = str_get_html("<div>foo <b>bar</b></div"); 
$b = $html->find('b',0);
$b->outertext = '';
echo $html->innertext; // вернет <div>foo</div>, элемент удален из HTML
// но
echo count($html->find('b')); // вернет 1, в дерево элемент присутствует

при желании  мы даже можем вернуть элемент на место

$b->outertext = '<span>bar</span>';
echo $html->innertext;// вернет <div>foo<span>bar</span></div>

Для более эффективной навигации по дереву документа доступны методы

$e->children ( [int $index] )     Возвращает объект N-го прямого потомка, если индекс установлен, в противном случае возвращает массив всех дочерних элементов

$e->parent()    Возвращает родительский элемент.

$e->first_child() Возвращает первый дочерний элемент, или null, если ничего не найдено

$e->last_child() Возвращает последний дочерний элемент, или null, если ничего не найдено

$e->next_sibling() Возвращает следующий родственный элемент, или null, если ничего не найдено

$e->prev_sibling()       Возвращает предыдущий родственный элемент, или null, если ничего не найдено

пример

$html ="<div>
  <b>bar</b>
  <b>foo</b>
  <span>arg</span>
  <div>
    <b>tor</b>
  </div>
</div>"; 

Все дочерние элементы разные, как-то подобрать к ним селектор проблематично. Поэтому воспользуемся описанными методами.

$html  = str_get_html($html);
$div = $html->find('div',0);
$i = 0;
while($item = $div->children($i++)){
	echo $item->innertext;
} 

либо так

$item = $div->children(0);
echo $item->innertext;
while($item = $item -> next_sibling()){
   echo $item->innertext;
} 

Данные методы полезны при разборе таблиц, элементы которых, как правило, структурированы, но не имеют идентифицирующих атрибутов.

Ну и последняя фишка это вызов callback функции на найденный элемент

function my_callback($element) {
       if ($element->tag=='span')
                $element->outertext = '<b>'.$element->innertext. '</b>';// заменим все span элементы на b
} 
$html  = str_get_html('<span>bar</span><span>pole</span><span>sushi</span><a>okno</a>');
// Регистрация функции обратного вызова с ее именем
$html->set_callback('my_callback');// вызов функции произойдет при конвертации объекта в строку
echo $html; // на самом деле, при этом вызывается магический метод __toString, он и запускает наши калбяки

На экране мы увидим 

<b>bar</b><b>pole</b><b>sushi</b><a>okno</a>

 

Доступ к атрибутам элементов осуществляется напрямую

foreach($html->find('img') as $img) echo $img->src;
//или
echo $html->find('img',0)->src;

Хватит теории, перейдем к практике

Загрузим n фотографий из поисковой выдачи Yandex Картинок. http://images.yandex.ru/

require_once 'simple_html_dom.php';
// поисковый URL
$url = 'http://images.yandex.ru/yandsearch?text='.urlencode('Джессика Альба').'&rpt=image';
$n = 2;
// загружаем данный URL
$data = file_get_html($url);
// очищаем страницу от лишних данных, это не обязательно, но когда HTML сильно захламлен бывает удобно почистить его, для дальнейшего анализа
foreach($data->find('script,link,comment') as $tmp)$tmp->outertext = '';
// находим все изображения на странице
if(count($data->find('div.b-image img'))){
	$i = 1;
	foreach($data->find('div.b-image img') as $img){
		// выводим на экран изображение 
		echo '<img src="'.$img->src.'"/>';
		// и скачиваем его в файл
		file_put_contents('data/'.($i++).'.jpg',file_get_contents($img->src));
		if($i>$n)break; // выходим из цикла если скачали достаточно фотографий
	}
}
$data->clear();// подчищаем за собой
unset($data);

Как быть если нам нужно больше фото, чем лежит на одной странице?

Ответ прост: Код, приведенный выше, заключается в функцию, в html помимо фото находим еще  и URLвсех страниц, и рекурсивно вызываем данную функцию для этих страниц.

require_once 'simple_html_dom.php';
function getYandexImages($url,$findpages = true){
	static $i = 1;
	$n = 200;
	// загружаем данный URL
	$data = file_get_html($url);
	// очищаем страницу от лишних данных, это не обязательно, но когда HTML сильно захламлен бывает удобно почистить его, для дальнейшего анализа
	foreach($data->find('script,link,comment') as $tmp)$tmp->outertext = '';
	// находим URL страниц только для первого вызова функции
	if( $findpages and count($data->find('div.b-pager__pages a'))){
		foreach($data->find('div.b-pager__pages a') as $a){	
			// довольно распространенный случай - локальный URL. Поэтому иногда url надо дополнять до полного
			if( !preg_match('#^http://#',$a->href) )$a->href = 'http://images.yandex.ru'.$a->href;
			// и еще дна тонкость, & надо заменять на &
			$a->href = str_replace('&','&',$a->href);
			// вызываем функцию для каждой страницы
			getYandexImages($a->href,false);
		}
	}
	// находим все изображения на странице
	if(count($data->find('div.b-image img'))){
		foreach($data->find('div.b-image img') as $img){
			// выводим на экран изображение 
			echo '<img src="'.$img->src.'"/>';
			// и скачиваем его в файл
			file_put_contents('data/'.($i++).'.jpg',file_get_contents($img->src));
			if($i>$n)exit; // завершаем работу если скачали достаточно фотографий
		}
	}
	$data->clear();// подчищаем за собой
	unset($data);
}
// поисковый URL
$url = 'http://images.yandex.ru/yandsearch?text='.urlencode('Джессика Альба').'&rpt=image';
getYandexImages($url);

 

Все хорошо, 200 картинок лежат в папке data. Но их размер слишком мал.

Поэтому завершающим аккордом нашей практики будет загрузка увеличенной фотографии.

Для этого определим еще одну функцию

 

function getBigImage($url){
	$data = @file_get_contents($url);
	if(trim($data)=='')return false; // бывает что сайт недоступен, его фото мы не грузим
	$data = str_get_html($data);
	// находим фото
	if( count($data->find('#i-main-pic')) ){
		$dataimg = @file_get_contents($data->find('#i-main-pic',0)->src); // собачка нужна в если сервер нам вернул 404, это выозвет Warning:, поэтому экранируем ошибки
		if(trim($dataimg)=='')return false; // фото не доступно, его не грузим
		file_put_contents( 'data/'.md5($url).'.jpg', $dataimg ); // сохрпаняем в файл
	}
	$data->clear();// подчищаем за собой
	unset($data);
}

 

и слегка поправим getYandexImages

function getYandexImages($url,$findpages = true){
	global $i,$n;
	// загружаем данный URL
	$data = @file_get_contents($url);
	$data = str_get_html($data);
	// очищаем страницу от лишних данных, это не обязательно, но когда HTML сильно захламлен бывает удобно почистить его, для дальнейшего анализа
	foreach($data->find('script,link,comment') as $tmp)$tmp->outertext = '';
	// находим URL страниц только для первого вызова функции
	if( $findpages and count($data->find('div.b-pager__pages a'))){
		foreach($data->find('div.b-pager__pages a') as $a){	
			// довольно распространенный случай - локальный URL. Поэтому иногда url надо дополнять до полного
			if( !preg_match('#^http://#',$a->href) )$a->href = 'http://images.yandex.ru'.$a->href;
			// и еще дна тонкость, & надо заменять на &
			$a->href = str_replace('&','&',$a->href);
			// вызываем функцию для каждой страницы
			getYandexImages($a->href,false);
		}
	}
	// находим все изображения на странице
	if(count($data->find('div.b-image img'))){
		foreach($data->find('div.b-image a') as $a){
			if( !preg_match('#^http://#',$a->href) )$a->href = 'http://images.yandex.ru'.$a->href;
			$a->href = str_replace('&','&',$a->href);
			getBigImage($a->href);
			if($i++>=$n)exit; // завершаем работу если скачали достаточно фотографий
			echo '<script>document.getElementById("counter").innerHTML = "Загружено: '.$i.' из '.$n.' фото";</script>';
			flush();
		}
	}
	$data->clear();// подчищаем за собой
	unset($data);
}
// поисковый URL
$i = 1;
$n = 20; // будем грабить 20 картинок
$url = 'http://images.yandex.ru/yandsearch?text='.urlencode('Джессика Альба').'&rpt=image';
getYandexImages($url);

 

Вот и все, наслаждаемся фото великолепной Джессики Альбы. Надеюсь меня простит Яндекс, ведь по сути фото грабится не с их серверов, а с прямиком с сайтов, где они лежат.

Кроме того это всего лишь демонстрация работы. Думаю никому в здравом уме, не придет в голову парсить Яндекс с помощью file_get_content. Данную библиотеку можно применять и в мирном программировании. К примеру в качестве шаблонизатора для CMS. Почему нет, с хорошим кешированием будет очень удобная штука.

 При больших объемах сайтов доноров,  неплохо бы разбить все на потоки.

А используя описанный мой скрипт сортировки изображений по цвету, можно собрать неплохую отсортированную базу, фотографий знаменитостей.

И, как всегда, выкладываю все исходники

UPD: Благодаря пользователю Диме, выяснилось, что библиотека обновилась 2011-07-14 и имеет версию 1.5. Нововведений не много, однако самый главный баг, с которым сталкивались все, кто пользовался библиотекой, а именно утечка памяти, устранен. На то она и версия 1.5, а не 2.0. Радует, что проект все же поддерживается и развивается. Ждем новых релизов.

Рассказать друзьям
author.jpg

Платная консультация по вопросам 1500 руб/час

Прочитали статью и остались вопросы? Меня зовут Валерий и я её автор. С радостью объясню Вам в скайпе все затруднительные моменты, которые остались за рамками статьи!

Подробнее ...

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


Комментарии   

Игорь
0 # Игорь 01.05.2011 01:42
Вот скажем есть стр.:

http://cell-phones.shop.ebay.com/Cell-Phones-Smartphones-/3312/i.html?LH_BIN=1&_trkparms=65%253A10%257C66%253A4%257C39%253A1&rt=nc
&_dmpt=Cell_Phones&_ds=1&_fcid=168&_localstpos=&_sc=1&_sticky=1&_stpos=&_trksid=p3286.c0.m14
&gbr=1&_sop=15&_sc=1

Как спарсить картинки отдельно, описание отдельно, цену отдельно?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
-1 # Leroy 03.05.2011 14:00
$site = 'http://cell-phones...=15&_sc=1';
$data = file_get_html($site);
foreach($data->find('#v4-56 table') as $table){
echo @$table->find('img',0)->src.'=>';
echo @$table->find('td.prc div.g-b',0)->plaintext.'=>';
echo @$table->find('div.ttl',0)->plaintext.'
';
flush();
}
$data->clear();
unset($data);


вродь все просто, откройте сайт в каком-нибудь DOM инспекторе и смотрите его структуру.

Встроенный дом инспектор есть в Опере,Хроме и IE начиная с 8 вродь. На файрфокс есть фаербаг.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Павел
+1 # Павел 19.06.2011 05:07
"str_get_htm – на вход получает обычную строку" тут функция должна быть str_get_html
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Павел
+2 # Павел 19.06.2011 05:08
спасибо за статью
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Иван
0 # Иван 16.07.2011 21:51
Здравствуйте, написал вот такой парс

$html = file_get_html("D:\Files\сайт\detail_ajax.htm");



foreach($html->find('script,link,comment') as $tmp)$tmp->outertext = '';

if(count($html->find('span[class="titleproductname]'))){

foreach($html->find('span[class="titleproductname] ') as $a){



print $title = $a->plaintext."
";





}

}



if(count($html->find('.textproductdescription'))){

foreach($html->find('.textproductdescription') as $a){



echo $a->innertext;





//при echo в цикле выводится все строки с дивов .textproductdescription

но когда присваеваю значение переменной, выводиться с переменной только одна строка, последняя



}

}

$image = $html->find('img',0)->src;

//echo $title, $text, $image;

$html->clear();

unset($html);

//подскажите как в цикле присвоить значение переменной?

или записать результат многих дивов?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Игорь
0 # Игорь 05.10.2011 00:43
Просто, спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Николай
-1 # Николай 05.10.2011 16:42
Спасибо вам огромное...
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Слава
-1 # Слава 21.10.2011 04:43
foreach($data->find('div.b-pager__pages a')

что такое div.b-pager__pages a не могу разобраться
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
1341234
-2 # 1341234 10.11.2011 01:58
блин. больше не статью читаю, а по бокам рисую. ни какой работы
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Лариса
0 # Лариса 10.11.2011 16:54
А как делается такой фон? Оч забавно и ново. :) И читаешь и рисуешь одновременно
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Олег
0 # Олег 17.01.2012 17:11
Очень полезная и интересная статья. Помогла реализовать мои идеи в кратчайшее время. Все в простой и доступной форме. Автору СПАСИБО.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serhey
-2 # serhey 19.01.2012 04:41
да очень полезная статья !!!! Спасибо автору !!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Sleepwalker
-1 # Sleepwalker 07.02.2012 16:05
// очищаем страницу от лишних данных, это не обязательно, но когда HTML сильно захламлен бывает удобно почистить его, для дальнейшего анализа

foreach($data->find('script,link,comment') as $tmp)$tmp->outertext = '';



Скажите, а здесь разве $data изменяется? разве изменения не происходят в локальной переменной $tmp ?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
lerik
-1 # lerik 07.02.2012 21:06
Для интереса попробуйте такой код
$g= array(1,2,3);
foreach($g as $j)
$j++;
print_r($g);
будете приятно удивлены
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
opozZzum
-1 # opozZzum 07.08.2012 12:07
а разве не foreach($g as &$j) ?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
-1 # Leroy 07.08.2012 21:07
опа это я ступил=) да вы правы именно так с &
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 07.08.2012 21:08
тут немного ошибся, вообщем дело в том что сам $tmp как свойство сеодержит ссылку на некий объект который и изменяется, если мы будем менять сам $tmp то ничего не измениться, а вот если одно из его полей то изменения произойдут
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Игорь
-1 # Игорь 10.02.2012 03:37
Привет ребята. Я получил список ссылок с моего сайта такого типа:

1 -ссылка1

2 -ссылка2

1 -ссылка3

2 -ссылка4



что мне нужно дописать в коде, чтобы выводилось так:



1 -ссылка1

1 -ссылка2

1 -ссылка3

1 -ссылка4



у нужной мне ссылки нету атрибутов, для её поиска...

Заранее спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Svetlana
-1 # Svetlana 20.02.2012 02:35
Спасибо, буду разбираться...



Ждем возвращения из армии!

Если, что надо пишите, вдруг сможем помочь!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Сергей
-1 # Сергей 21.02.2012 21:01
не могу разобраться с загрузкой файлов



file_put_contents('data/'.($nomer).'.jpg',file_get_contents($img->src));



сохраняет нужное количество фалов в папке, но все они пустые

$img->src - содержит правильный путь к фото на сайте .. в чем беда не пойму :(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Сергей
-1 # Сергей 21.02.2012 21:02
сам спросил, сам ответил :)

как только написал вопрос понял в чем проблема - оказывается в $img->src хранился относительный путь в фото, банально добавил название домена и все ок.



спасибо за помощь :) !
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Stas
-1 # Stas 02.03.2012 13:05
Добрый день!

Имеется следующий кусок кода:



Автор:А.Мецгер


ISBN:978-5-378-02142-0


Переплет:


Страниц:16


Формат:200х280



Со СПАНами все понятно, но нужно присвоить переменным значения,которые между тегами /strong и br или /strong и /span (для последнего случая)



Например:

MyAuthor = "А.Мецгер"

MyBinding = ""



Причем вся строка, например (ISBN:978-5-378-02142-0
) может отсутствовать.

Заранее благодарен.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Stas
-1 # Stas 02.03.2012 13:10
Простите, заменяю текст



Добрый день!

Имеется следующий кусок кода:

{span class="block"}

{strong}Автор:{/strong}А.Мецгер{br}

{strong}ISBN:{/strong}978-5-378-02142-0{br}

{strong}Переплет:{/strong}{br}

{strong}Страниц:{/strong}16{br}

{strong}Формат:{/strong}200х280

{/span}

Со СПАНами все понятно, но нужно присвоить переменным значения,которые между тегами /strong и br или /strong и /span (для последнего случая)



Например:

MyAuthor = "А.Мецгер"

MyBinding = ""



Причем вся строка, например ({strong}ISBN:{/strong}978-5-378-02142-0{br}) может отсутствовать.

Заранее благодарен.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Димон
-1 # Димон 18.04.2012 15:49
Супер! Молодчага что написал! Регулярка достает!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Антон
-1 # Антон 10.06.2012 04:43
Нужен специалист для создания парсера и настройки переноса контента. Пишите на почту k-klient собак mail.ru
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
ygor
-1 # ygor 12.06.2012 16:46
Что-то не пойму, как спарсить определённое значение скажем есть 1.txt файл с содержимым:

/pages/13674/1367437.shtml

/pages/14072/1407291.shtml

/pages/14107/1410773.shtml

/download.php?id=1420841.mp3

/reklama.shtml

/rp/list.php

/spages/events.shtml

Каким образом их этого файла выбрать имено строку: /download.php?id=1420841.mp3 ??? Спасибо заранее.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
-1 # Leroy 12.06.2012 18:04
$data = explode("\r",file_get_contents('1.txt'));
foreach($data as $st){
if( preg_match("#\.mp3$#",$value) ){
echo $value.'
';
}
}


Я думаю тут все понятно) а вообще это элементарная работа со строками

P.S. Возможно что-то не работает, я только пришел с армии =)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
ygor
0 # ygor 12.06.2012 18:47
Поздравляю с приходом))), Но действительно, не что-то, а вообще не работает (((
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
ygor
0 # ygor 12.06.2012 20:46
Да что такое, вообще запутался, ниче не выходит, пол дня бьюсь, может кто подскажет? бакс на кошелёк перечислю... Вот проблемма с выражением выше ничего не получилось. Даю прямой текст:

надо с этой страницы:

http://zaycev.net/pages/14208/1420841.shtml

выдрать ссылку **********.mp3 она одна там, выкладывайте вариант с Z Кошельком... СПС
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 12.06.2012 21:28
элементарно

$data = file_get_contents('http://zaycev.net/pages/14208/1420841.shtml');
if( preg_match_all('#href="([^"]*\.mp3)"#Uis',$data,$list) )
print_r($list[1]);//в $list[1] будут все нужные нам ссылки со страницы
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 21.06.2012 16:44
подскажите как выбрать элемент по класу если класов несколько через пробел?



....

Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 21.06.2012 17:12
Как вариант

$html = str_get_html('<div> <div class="div1">1</div>
<div class="div1">2</div>
<div class="div1 div2">3</div>
<div class="div1">4</div>
</div>');
$divs = $html->find('div.div1[class*=div2]');
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
+1 # Leroy 21.06.2012 17:21
ну или напрямую
$html->find('div[class=div1 div2]');
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 21.06.2012 17:45
спасибо. еще вопрос метод clear вызывает ошибку

ErrorException [ Fatal Error ]: Allowed memory size of 134217728 bytes exhausted (tried to allocate 59008046 bytes)



фреймворк kohana
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 21.06.2012 17:59
это не метод clear ее вызывает, а его не своевременный вызов. Где-то что-то не уничтожаете. Я писал про это
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виктор
0 # Виктор 24.06.2012 18:47
А вот у меня через полминуты выдает ошибку:

Fatal error: Maximum execution time of 30 seconds exceeded in simple_html_dom.php on line 70



Кстати, оригинальные примеры с Джессикой Альбой также не дорабатывают до конца, если увеличить количество выкачиваемого с 20 до, хотя бы, 500.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 24.06.2012 20:17
Знакомые грабли. Добавьте в начало скрипта эту строчку
ini_get('safe_mode') or set_time_limit(0);
и будет Вам счастье)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виктор
0 # Виктор 25.06.2012 05:28
Всякий должен сам наступить на грабли! Спасибо - работает.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Викуля
0 # Викуля 29.06.2012 00:22
привет:)

парни, а совсем тугой можно помочь:)?

мне надо простейшую программульку -выдрать номера телефонов из одной категории сайта обьявлений.

никаких наворотов больше не надо - только голый текст с номерами тел. в столбик - шеф поручил составить такой список - я за день только 200 номеров собрала.

была бы очень благодарна за помощь:)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 29.06.2012 02:43
пиши на ящик, конешно помогу
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Дима
0 # Дима 11.08.2012 01:00
обнови текст статьи- библиотека обновлена в 2011 году, если я правильно понял))
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Миша
0 # Миша 26.08.2012 02:15
Спасибо, статья очень полезная
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Евгений
0 # Евгений 30.08.2012 19:39
Имеется div вида


<div class="classname">
<p><strong>Текст</strong>: <strong>Текст</strong>.<br /><br /><strong>Текст</strong>: Текст<br /><strong>Текст</strong>: Текст<br /><strong>Жанр</strong>: Текст<br /><strong>Текст</strong>: Текст<br /><strong>Текст</strong>: Текст<br /><strong>Текст</strong>: Текст<br /><strong>Текст</strong>: Текст</p>
<p style="text-align: center;"><strong>Нужный текст1</strong></p>
<p style="text-align: center;"><iframe src="Нужная ссылка1" width="607" height="360" frameborder="0"></iframe></p>
<p style="text-align: center;">Нужный текст2</p>
<p style="text-align: center;"><iframe src="Нужная ссылка2" width="607" height="360" frameborder="0"></iframe></p>
<p style="text-align: center;"><strong>Нужный текст3</strong></p>
<p style="text-align: center;"><iframe src="Нужная ссылка3" width="607" height="360" frameborder="0"></iframe></p>
<p style="text-align: center;">Нужный текст4</p>
<p style="text-align: center;"><iframe src="Нужная ссылка4" width="607" height="360" frameborder="0"></iframe></p>
<p style="text-align: center;"><strong>Нужный текст5</strong></p>
<p style="text-align: center;"><iframe src="Нужная ссылка5" width="607" height="360" frameborder="0"></iframe></p>
</div>


Подскажите пожалуйста как распарсить и вывести нужный текст и соответствующую ему нужную ссылку. Всю голову сломал.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 30.08.2012 19:55
ну на вскидку примерно так
$data = str_get_html('код');
foreach($data->find('iframe') as $iframe){
echo $iframe->src.' '.$iframe->parent()->prev_sibling ()->plaintext.'<br>';
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 24.09.2012 15:10
Здравствуйте! Скачал ваши примеры, работает только один с ярлыками вашего блога. Пробовал спарсить по вашей инструкции спец предложения http://www.aviasales.ru/, ну не как не получается, страничка пустая все время.:(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 24.09.2012 17:10

Я ведь написал, что серьезные парсеры не пишутся через file_get_contents, нужно использовать curl


function request($url,$post = 0){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url ); // отправляем на
curl_setopt($ch, CURLOPT_HEADER, 0); // пустые заголовки
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файл
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');
curl_setopt($ch, CURLOPT_POST, $post!==0 ); // использовать данные в post
if($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
echo request('aviasales.ru');


все отлично работает, почитайте эти статьи Авторизация на сайте при помощи curl php и Многопоточные парсеры
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 24.09.2012 23:26
Спасибо за наводку, но признаюсь, мало что понял.

1. Обязательно нужна авторизация на сайте, что парсить данные?

2. Не понял тот пример что вы написали выше. Как он применим к моей ситуации.

Попробовал сделать следующим образом:

<? php

include_once('simple_html_dom.php');//подключаем библиотеку

//Инициализируем cURL-сессию
$ch = curl_init ("http://www.aviasales.ru/");

//открываем для записи файл yandex.txt
//сюда внесём исходный html-код
$fp = fopen ("avia.txt", "w");

//указываем куда копировать содержимое
curl_setopt ($ch, CURLOPT_FILE, $fp);

//Заголовок - не выводим
curl_setopt ($ch, CURLOPT_HEADER, 0);

//Поехали!
curl_exec ($ch);

//Закрываем cURL-сессию
curl_close ($ch);

//Закрываем дексриптор файла
fclose ($fp);

//И вставляем на страницу полученный код
include 'avia.txt';
?>


Можно как то по подробнее рассмотреть мою ситуацию?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 24.09.2012 23:29
Кстати как написано в статье сделать проверку PHP.ini на предмет включена cURL или нет. Сделал.



cURL support - enabled

cURL Information -libcurl/7.20.0 OpenSSL/0.9.8o zlib/1.2.3
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 24.09.2012 23:39
Убрал:


include_once('simple_html_dom.php');//подключаем
библиотеку


пропала ошибка 500, с но все равно все пусто. Я если это проделать с yandex то парситься на ура! Подскажите что нужно сделать?:)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.09.2012 03:16
я проверил, мой пример выше работает прекрасно. Вам всего лишь нужно было сменить урл с aviasales.ru на http://www.aviasales.ru/specpredlozheniya-aviakompaniy и все заработает

авторизовыватся на сайте не нужно, дал линк на статью чтобы почитали про курл и общие принципы
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 25.09.2012 10:04
Видимо я совсем не понимаю. В вашем примере нет
$url='aviasales.ru';


Значит нужно произвести замену в
echo request('aviasales.ru');
на
echo request('http://www.avi...aniy');
Правильно понял вас?

Я создал cookie.txt в той же директории где и лежит index.php, соответственно подправил путь:
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'cookie.txt');


т.е. получается:
<? php
include_once('simple_html_dom.php');
function request($url,$post = 0){
$ch = curl_init();//здесь разве не нужно прописать адрес страницы для которой открывается сессия?
curl_setopt($ch, CURLOPT_URL, $url );//В вашем примере нигде не описана перменная $ur
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR,dirname(__FILE__).'/cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE,dirname(__FILE__).'cookie.txt');
curl_setopt($ch, CURLOPT_POST, $post!==0 );
if($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
echo request('http://www.aviasales.ru/specpredlozheniya-aviakompaniy'); //здесь мне вообще схема работы не понятна
?>


Но у меня все равно появляется сообщение с кодом 500. Честно говоря уже перечитал все не на раз. И хочу разобраться, но как то еще запутаннее получается.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 25.09.2012 10:15
Не верные пути указал в выше указанном файле в моем случае:

curl_setopt($ch, CURLOPT_COOKIEJAR,'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE,'cookie.txt');
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.09.2012 12:44
вы правильно поняли, нужно поменять именно там.

создавать cookie.txt не надо, он автоматически создастся, если сервере вернет куки

$ch = curl_init(); - адресс можно не прописывать, если он пишется ниже

curl_setopt($ch, CURLOPT_URL, $url );

в вашем коде в 15 строчке ошибка, нет слеша после dirname(__FILE__)

ошибка 500 возникает скорее всего потому, что в скрипте есть ошибка, а ваш сервер настроен на то чтобы не выдавать ошибок php, почитайте статейку как включить показ ошибок в php
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 25.09.2012 14:44
Огромное спасибо! Сделал чтобы выводились ошибки по php, и исправил недочеты.:)

Очень благодарен!

А не подскажете дальше что изучать, чтобы вывести нужный мне контент, а не все в подряд?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 25.09.2012 15:55
Решил с простого вашего примера начать: Вывести контент с тегом "a".

Не могу понять что именно нужно вставить в $html = str_get_html('__________');

Пробовал и имя функции - request и $url, толку нет.

Вставлял после : return data;
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.09.2012 16:00
str_get_html(request('http://xdan.ru'));

str_get_html - на вход принимает строку

file_get_html - на вход принимает url либо адрес файла
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 25.09.2012 22:37
Спасибо, понял что не так делал. вот что у меня получилось:

?<?php
ini_get('safe_mode') or set_time_limit(0);
function request($url,$post = 0){
$ch = curl_init();
$url = 'http://www.aviasales.ru/';
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEJAR,dirname(__FILE__).'/cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE,dirname(__FILE__).'/cookie.txt');
curl_setopt($ch, CURLOPT_POST, $post!==0 );
if($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}

include_once('simple_html_dom.php');
$html = str_get_html(request('http://www.aviasales.ru/'));
if($html->innertext!='' and count($html->find('#holliday_prices'))){
foreach($html->find('#holliday_prices') as $blok){
echo $blok;
}
}
?>


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

 foreach($html->find('#holliday_prices') as $blok){...


Пробовал сделать следующее, но видимо не то:
$blok->find('a', 1)->href = 'www.test.ru';
Прошу очередной раз вашей помощи:)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 26.09.2012 12:45
наверно как-то так


foreach( $html->find('#holliday_prices a') as $a){
$a->href = str_replace('http://www.a..s.ru/','http://xdan.ru',$a->href);
}
echo $html->find('#holliday_prices',0)->innertext;
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 26.09.2012 14:16
Спасибо, работает. Я сделал немного по другому:
if($html->find('#holliday_prices')){
foreach($html->find('#holliday_prices') as $blok){

}
}

$newurl = "http://test.ru/";
echo preg_replace('#(\<a[^\>]*href\=\")(.*?)(\"\>)#', "$1{$newurl}$3", $blok);


Сделал так, потому что ваш вариант работает только с конкретной ссылкой:)Теперь надо понять, как это дело украшать)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 26.09.2012 14:32
остается понять, что вы делаете на этой странице, раз все равно используете регулярки =)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 26.09.2012 16:15
Честно говоря, просто свое решение я нашел раньше и решил его отобразить здесь. Но пытаюсь понять как сделать это не через регулярки. PHP я только начинаю изучать, поэтому может получается каша в коде:)Кстати, вам бы форум бы сделать, где можно было бы обсуждать статьи и свои скрипты на основе их:)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 26.09.2012 16:22
А как с вами можно связаться? просто аська указанная в вашем профеле, принадлежит другому человеку.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Денис
0 # Денис 25.09.2012 05:53
Отличная статья, спасибо! Все что нужно оговорено. Пишите еще.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Евгений
0 # Евгений 25.09.2012 11:43
Данная статья была для меня крайне полезна, спасибо автору.

Когда задавал вопрос, подписался на уведомления о комментариях, но как теперь отписаться?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.09.2012 12:05
развиваю движок, извините за неудобство. Сейчас добавлю такой функционал
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.09.2012 12:22
хотя нет соврал, есть такая возможность, напишите комент и уберите галочку Подписаться на уведомления о новых комментариях
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.09.2012 13:45
теперь есть такая возможность, хотя вы наверно уже отписались
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
qazarius
0 # qazarius 01.10.2012 05:08
Спасибо

Кажется помогло
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр
0 # Александр 26.09.2012 16:51
А вы можете написать про кодировку?

Вот такая ситуация:

У меня CMS на win1251, а сайт донер на UTF8, парсинговый скрипт соответственно пишется в кодировке UTF-8. Как только этот скрипт подгружаю на сайт в нужное место, весь спарсенный контент появляется ввиде символов. Как сделать так чтобы Данные нормально отображались и при кодеровке win1251&
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 26.09.2012 17:02
$text = iconv('utf-8','windows-1251',$text);


работает не всегда, т.к. многих символов в win, которые есть в utf, попросту нет.

еще есть mb_convert, загуглите

еще на php.net под описанием iconv куча велосипедных реализаций, если iconv не справляется то попробуйте их, по опыту скажу, что 100% рабочего решения вы не найдете, у каждого сайта свои тонкости. Это та еще проблемка
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Jeka
0 # Jeka 29.09.2012 01:14
Прочитал первые несколько слов, сразу захотелось выразить несогласие, с помощью регекспов можно распарсить разметку любой сложности, если уметь ими пользоваться. ИМХО
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 30.09.2012 22:49
уверяю вас, не любой, пользовался регэкспами до знакомства с этой библиотекой, самые проблемы возникают когда разметка у одной и той же страницы различается в зависимости от контента, никакие регэкспы не помогут если при заполнении юзер может сам вводить произвольные теги в содержание, тогда только dom
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
levarm
0 # levarm 04.10.2012 21:28
Подскажите как персить текст группируя по class: ico-phone, ico-ICQ, ico-adress сложность заключается в том что эти элементы стоят в span перед нужным для персинга текстом.

<div class="padB10 wrapMargin">
<div class="wrapIcons"><span class="ico-set ico-phone"></span>9131258 </div>
<div class="wrapIcons"><span class="ico-set ico-phone"></span>(846) 248-32-02 </div>
<div class="wrapIcons"><span class="ico-set ico-ICQ"></span>571-524-990</div>
<div class="wrapIcons"><span class="ico-set ico-adress"></span> Адрес предприятия</div>
</div>
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 04.10.2012 21:50

$data = str_get_html('код');
foreach($data->find('ico-phone,ico-ICQ,ico-adress') as $item){
// 1 вариант
echo $item->next_sibling()->innertext; // не уверен, что сработает
// 2 вариант
echo $item->parent()->innertext; // если все как в вашем примере
// 3 вариант
$item->parent()->find('ico-phone,ico-ICQ,ico-adress',0)->outertext = '';
echo $item->parent()->innertext;
}
// 4 вариант
foreach($data->find('wrapIcons') as $item){
echo $item->innertext;
}


не один из вариантов не проверял, и думаю кусок кода вы привели для примера, но думаю ход мыслей понятен
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Bane
0 # Bane 16.10.2012 17:18
Спасибо автору! Начал знакомство с парсерами с этой статьи. Теперь могу парсить практически все.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serg
0 # serg 01.11.2012 03:42
А как отсюда спарсить title и саму картинку, да еще и 2 слэша мешают((

<img class="lazy" title="testing image" data-src="//test.com/img/test.img" />
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 01.11.2012 13:00
подобные вещи типа echo $a->src; делаются через "магические" методы php, т.е. эта запись эквивалентна echo $a->__get('src'); а в вашем случае будет echo $a->__get('data-src');, однако чтобы в эти дебри не углубляться у библиотеки есть стандартные методы getAttribute и setAttribute эквивалентные javascript'ским
$img = str_get_html('<img class="lazy" title="testing image" data-src="//test.com/img/test.img" />');
echo str_replace('//','/',$img->getAttribute('data-src'));
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
IgorA100
0 # IgorA100 03.11.2012 17:00
Добрый день.

Столкнулся с проблемой кодировки :(

Есть страница: http://beward.ru/goods/?dir1=1&dir2=14 в кодировке "windows-1251"



Есть рабочая ф-ция


function curl_gets_NEW($url){
$ch = curl_init();

$allUseragents = array(
"Opera/9.23 (Windows NT 5.1; U; ru)",
"Mozilla/16.0.1 (compatible; MSIE 5.12; Mac_PowerPC)",
"Opera/8.54 (Windows NT 5.1; U; ru)",
"Opera/9.21 (Windows NT 5.0; U; ru)",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0; .NET CLR 2.0.50727)",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; 3305; Wanadoo 6.1)",
);

$agent = $allUseragents[array_rand($allUseragents)];
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,//return data as string
CURLOPT_CONNECTTIMEOUT => 10,//timeout
CURLOPT_TIMEOUT => 100,
CURLOPT_USERAGENT => $agent,
CURLOPT_HEADER => 0,
CURLOPT_NOPROGRESS => 0,
CURLOPT_FAILONERROR => 0,
CURLOPT_FOLLOWLOCATION => 0,
CURLOPT_SSL_VERIFYPEER => 0,
)
);


$data = curl_exec($ch);
curl_close($ch);
return $data;
}


Читаем:

$url = 'http://beward.ru/goods/?dir1=1&dir2=14';

$content = curl_gets_NEW($url);

Все нормально!

Далее, читаем: $HTMLtext = str_get_html($content,true,true,'windows-1251');

и получаем вместо русских букв пустоту :(

Если не указывать кодировку при "str_get_html", то появляется белеберда.

mb_detect_encoding тоже не помогает. Вообще вошел в ступор :(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Lucky_7
+1 # Lucky_7 04.11.2012 11:01
Вы в какой кодировке работаете-то? Надо все привести к общему знаменателю - то есть если ваш скрипт и база работают с UTF-8, то вам надо результаты парсинга сконвертировать в UTF-8. Тут поможет iconv().

А вообще я бы советовал работать с чистым DOMDocument через xpath без использования дополнительных библиотек.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
IgorA100
0 # IgorA100 04.11.2012 16:56
Работаю в win-1251

Про приведение к единой кодировке я в курсе, но ни iconv(), ни mb_detect_encoding() не помогали.

Все оказалось банально просто, сайт говорит что кодировка win-1251, а реально контент на нем в win-1252.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виталий
0 # Виталий 28.11.2012 10:05
В общем есть сайт-http://auctions.a-automarket.com/auctions/?p= project/searchform&s&ld при авторизации выдаёт форму поиска, так вот эту форму нужно встроить в свой сайт. Как это реализовать? Узал simplehtmldom_1_5, но так и не разобрался как зайти на закрытую страницу средствами php( Нашел «lxml» библиотеку для парсинга, но не знаю есть ли смысл тратить время на её изучение...В общем был бы благодарен за помощь, а если конкретно укажите что и как делать готов материально поблагодарить)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 28.11.2012 15:27
все тоже самое что и обычный парсинг, за исключением того что сперва нужно авторизоваться
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Максим
0 # Максим 29.11.2012 21:21
Подскажите пожалуйста. есть такой HTML




<dl class="catalog">
<dt>
<dd>
<dd>
<dd>
</dl>




В тэгах есть еще вложенные , это я скопировал не раскрыв их.



Мне нужно занести в массив, делаю так:


$cat = $data->find('.catalog dd');




И в $cat добавляются все тэги и вложенные все, а мне надо только которые первые, не глубже. Как можно это сделать?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 30.11.2012 13:02
в топике есть примеры перебора дочерних элементов, либо методом children либо методом next_sibling
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Dexel
0 # Dexel 03.12.2012 23:28
Загрузка обеих процессоров под 100% при выполнении команды str_get_html(str)

Может из-за того, что страница перекодирована из win1251 в UTF-8
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 04.12.2012 13:45
может просто страничка большая?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Никита
0 # Никита 07.12.2012 02:19
Как перекодировать полученные данные с сайта, который на utf-8, так как при выводе у себя (cp1251) фрагмент с кирилицей "169 р." отображается как "169 СЂ."



iconv не работает
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 07.12.2012 13:21
перевод из большей кодировки в меньшую вообще сопряжен с такими вещами, потому как в cp1251 тупо меньше букавак, панацею я не нашел, каждый раз помогал определенный конвертер. Искать их стоит в комментах к iconv на php.net
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Алексей
0 # Алексей 19.12.2012 12:06
Отличная статья.

Автору спасибо. Как раз необходим был хороший пример помимо мануала.

Я в парсинге новичок, но появилась такая необходимость.

Подскажите, как правильно организовать парсер новостных сайтов. Я так понимаю, делать это с сервера, на котором расположен сайт агригатор не стоит?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 19.12.2012 13:23
ну вообще можно и сделать почему нет. Новостники вряд ли имеют сколько нибудь сильную защиту. Обычно он почти все через рсс выдают, грабь не хочу. Даже эта либа не нужна
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
naut
0 # naut 02.01.2013 21:41
Привет, Друзья!

Всех с Новым годом! Ура!

Помогите, запутался, не пойму что не так (новичёк-самоучка, что с меня взять))).

Вопрос в следующем.

Извлек страницу, распарсил этой чудной библиотекой, на экран все выводится в лучшем виде, но при записи в файл (стоит задача сохранить в один файл все ссылки) получается не 1 файл со списком N-ссылок, а N-файлов с ОДНОЙ каждой последующей ссылкой. Уже всякие варианты перебрал, менял циклы всякие, получается либо последняя ссылка в одном файле, либо как уже описал. Вот кусок кода где происходят итерации (подскажите ошибку):



$html= str_get_html($str);

$n = count($html->find('a, href'));

foreach($html->find('script,comment,image,img, png, jpg') as $tmp)$tmp->outertext = '';

if(count($html->find('a'))){

$i=0;

foreach($html->find('a') as $links){

echo $links->href .' ('. $links->innertext. ')
';

$result = file_put_contents(($i++).'Links.txt', $links->href);

if($i==$n)break;





if ($result) echo 'Данные в файл успешно занесены.';

else echo 'Ошибка при записи в файл.';



Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Нурбол
0 # Нурбол 20.02.2013 20:02
Здравствуйте

какой код тут надо сделать что бы взять цифры с 246.62 и 4.87 по отдельности в массив

Coğrafi Kuzeyden Kıble Açısı : 246.62 ° dir

2013 Senesi Ortası İçin Sapma Açısı : 4.87 ° dir

Pusula Kuzeyine Göre Kıble Açısı : (246.62) - (4.87) = 241.75 ° dir.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
-1 # Leroy 20.02.2013 20:12
if(preg_match_all('#[\d]+\.[\d]+#',$text,$list))
foreach($list as $dig)
echo $dig;


Учите регулярные выражения, хоть я и написал что только с помощью них парсить нельзя, но и совсем без них парсить сложновато
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Нурбол
0 # Нурбол 21.02.2013 12:08
Parse error: syntax error, unexpected T_VARIABLE, expecting T_PAAMAYIM_NEKUDOTAYIM in Z:\home\parser\www\inde1x.php on line 5

пишет!

2 дня перечитал все не получается! тестирую на денвере!

http://www.namazvakti.com/QAbout.php?cityID=8408 сайт откуда нужно взять 246.62 и 4.87

помогите пожалуйста! в долгу не останусь!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 21.02.2013 12:20
ну вы хоть код приведите, я же не телепат. Мой код я проверял, он работает
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Нурбол
0 # Нурбол 21.02.2013 12:33


include('simple_html_dom.php');



$html = file_get_html('http://www.namazvakti.com/QAbout.php?cityID=8408');



if(preg_match_all('#[\d]+\.[\d]+#',$text,$list))

foreach($list as ­$dig)

echo $dig;
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 21.02.2013 12:57
$html = file_get_contents('http://www.namazvakti.com/QAbout.php?cityID=8408');
if(preg_match_all('#[\d]+\.[\d]+#',$html,$list))
print_r($list[0]);
не понятно только, зачем вам simple_html_dom
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Нурбол
0 # Нурбол 21.02.2013 13:29
Вопрос решили спасибо сайту! буду заходить и поставлю в закладки)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Илья55
0 # Илья55 25.02.2013 21:46
Подскажите по simple_html_dom. Пробую простые парсеры.

Например:



include_once('C:/Users/Public/Apache/htdocs/Parser/simple_html_dom.php');

echo file_get_html('http://www.yandex.ru/')->plaintext;



Ругется:



PHP Fatal error: Call to undefined function mb_detect_encoding() in C:\Users\Public\Apache\htdocs\Parser\simple_html_d om.php on line 1234
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.02.2013 22:29
у вас не установлена библиотека php_mbstring.dll, поэтому и не доступна функция mb_detect_encoding. В php.ini нужно добавить строку extension=php_mbstring.dll ну и соответствующая dll должна лежать в папке с расширениями php
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Илья55
0 # Илья55 25.02.2013 23:11
Да, включил в php.ini extension=php_mbstring.dll.

Ну а сам php_mbstring.dll у меня лежит в C:\Program Files\PHP\ext, я так думаю это верно.



Подскажите а почему выводятся кракозябры типа:

Секс знакомства ru -

после парсинга
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.02.2013 23:32
кодировка отличается, ваша и сайта донора
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Илья55
0 # Илья55 27.02.2013 18:21
А где это можно исправить,не подскажите?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 27.02.2013 18:24
в настройках браузера)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
wolflingsu
0 # wolflingsu 13.05.2013 00:16
Полезно обрабатывать полученный HTML перед его парсингом. В том числе и кодировки:




function prepareForDOM($html, $encoding) {
$html = iconv($encoding, 'UTF-8//TRANSLIT', $html);
$html = preg_replace('/<(script|style|noscript)\b[^>]*>.*?<\/\1\b[^>]*>/is', '', $html);
$tidy = new tidy;
$tidy_config = array(
'drop-font-tags' => true,
'drop-proprietary-attributes' => true,
'hide-comments' => true,
'indent' => true,
'logical-emphasis' => true,
'numeric-entities' => true,
'output-xhtml' => true,
'input-encoding' => 'utf8',
'output-encoding' => 'utf8',
'wrap' => 0
);

$tidy->parseString($html, $tidy_config, $tidy_config['output-encoding']);
$tidy->cleanRepair();
$html = $tidy->value;
$html = preg_replace('#<meta[^>]+>#isu', '', $html);
$html = preg_replace('#<head\b[^>]*>#isu', "<head>\r\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />", $html);

return $html;
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 13.05.2013 11:10
осталось только узнать что за класс tidy
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
wolflingsu
0 # wolflingsu 14.05.2013 12:55
Leroy, вы шутите? =)

http://www.php.net/manual/ru/book.tidy.php
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Илья55
0 # Илья55 25.02.2013 22:22
Опечатка в Илья55 25.02.2013 18:20: включил extension=php_mbstring.dll а не extension=php_ldap.dll
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Илья55
0 # Илья55 25.02.2013 22:52
Подскажите почему при парсинге некоторых сайтов, например yandex,при:



include_once('C:/Users/Public/Ap­ache/htdocs/Parser/si­mple_html_dom.php');

echo ­­file_get_html('http://www.yandex.ru/')->plaintext;



пишет стандартное сообщение:



Этот веб-узел не может отобразить эту страницу

HTTP 500

Возможные причины:

Веб-узел находится в состоянии обслуживания.

На этом веб-узле обнаружена программная ошибка.



Попробуйте сделать следующее:

Повторите ввод адреса.



Перейдите на предыдущую страницу.



Подробнее



Эта ошибка (HTTP 500 - внутренняя ошибка сервера) означает, что на веб-узле, который вы хотите посетить, имеется проблема, препятствующая отображению нужной веб-страницы.



Тое есть у этих сайтов стоит защита от парсера?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.02.2013 22:57
т.е. серьезные сайты не стоит парсить file_get_html (который использует file_get_content), используйте cUrl а уже потом результат распарсивайте str_get_html
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Илья55
0 # Илья55 25.02.2013 23:00
Спасибо Leroy, уже читаю про cUrl
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Stan
0 # Stan 28.02.2013 21:59
Подскажите, как спарсить со страницы Base64, что б обрезало весь текст и теги, оставался чистый Base64, буду очень благодарен
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 01.03.2013 11:06
ну чисто теоретически base64 то набор букв и цифр некой длинны, чаще всего это длинна будет большая. Поэтому тут легко справится что-то вроде
if(preg_match_all('#[a-zA-Z0-9]{10,}[=]?#',$data,$result))
print_r(result);
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Stan
0 # Stan 01.03.2013 18:26
Спасибо за быстрый ответ! Буду пробывать :)

Отлично написали статью, с нее начал знакомиться с парсингом.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Федор
0 # Федор 02.04.2013 23:32
Добрый день!

Есть задачка:


$o = str_get_html('<a class="some class" onclick="return {"var1":{"var2":"val"},"var3":{}}" href="/some/href/">Text</a>');

var_dump($o);//["attr"]=> array(2) { ["class"]=> string(10) "some class" ["onclick"]=> string(8) "return {" }




Лажа в том, что атрибут href для ссылки получить не удастся... По идее все портит json, но как это обойти?

Есть идеи?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 03.04.2013 02:33
хоть я и написал, что регулярки применять для распарсивания DOM не стоит, для строк лучше их не найти. preg_match('#href="([^"]+)"#',$data,$list) вот и все
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Guest
0 # Guest 08.05.2013 15:51
Спасибо! Отличный мануал! Так же порадовал котейка, который просит отключить AdBlock - на мне сработало :)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Comeonandroid
0 # Comeonandroid 23.05.2013 08:26
Помогите, никак не могу заставить работать ваш парсер в нынешних условиях. Получилось скачать 30 картинок подставив нужные теги div.b-images-item__wrap img вместо div.b-image img, но вот получить ссылку на дальнейший поиск никак не удается, я нашел её в исходном коде, она в этом элементе если жать на неё из браузера со страницы исходного кода все нормально, но как я не пробовал запихнуть её в парсер следуя инструкциям ничего ен получается
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
nisampurger
0 # nisampurger 26.05.2013 17:53
у меня есть xml файл вот с таким содержанием:



...



...



как получить с помощью Simple HTML DOM значения атрибутов Code, HighPic, Title?

Заранее благодарен :)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
nisampurger
0 # nisampurger 26.05.2013 17:57
...

Product Code="1" HighPic="namepic.jpg" Title="titleproduct"

...
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Евгений
0 # Евгений 24.06.2013 10:33
Здравствуте, совсем новичок в php

Подскажите, взял такой скрипт:


require_once 'simple_html_dom.php';
$data = file_get_html('http://turbo-tor.com/all-foto-rewievs/');
if($data->innertext!='' and count($data->find('.entry-content a img'))){
foreach($data->find('.entry-content a img') as $b){
echo '<a href="" rel="rr" onclick="return jsiBoxOpen(this)" title="">'.$b.'</a>';
}
}


Хочу в htef="" подставить адрес картинки, но у меня не выходит.

Не могу правильно составить поиск и вытянуть в href.

Как правильно это сделать?

Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 24.06.2013 11:35
ну у img нет href, у него есть только src
echo '<a href="'.$b->src.'" rel="rr" onclick="return jsiBoxOpen(this)" title="">'.$b.'</a>';
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Евгений
0 # Евгений 25.06.2013 00:02
сорри, неправильно выразился, в $b сама картинка, отлично выводится,

нo в href мне надо поместить не src img, а адрес ссылки в которую заключен сам тег img.

тоесть парсю вот это:

<a href="http://turbo-tor.com/wp-content/uploads/2013/06/1212.png"  data-slb-group="240" data-slb-active="1" data-slb-internal="0">
<img class="alignnone size-medium wp-image-222" alt="1212" src="http://turbo-tor.com/wp-content/uploads/2013/06/1212-300x232.png" width="300" height="232"/>
</a>


просто примеров не нашол, либо не внимательно смотрел, как высунуть в одном цыкле вывести две переменные и подставиь их.

Получаеться img есть, а как второй парсинг подставить и правильно вытянуть, не могу.



Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 25.06.2013 03:30
невнимательно читали

$b->parent() Возвращает родительский элемент.

$b->parent() ->href
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Евгений
0 # Евгений 25.06.2013 08:09
Огромное спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
doctor
0 # doctor 01.07.2013 21:26
Подскажите пожалуйста, а как парсить разные значения и забивать их в массив, т.е. span class=today и span class=wday в массив с ключем 1, а все остальное к примеру td class=time, так как первые меняются, а последующие повторяются?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
doctor
0 # doctor 02.07.2013 08:06
Вот код для примера:

<span class=today>Понедельник 22 июня</span><td class=time>11 ч.</td><span class=wday>Вторник 23 июня</span><td class=time>12 ч.</td>


значения span с классами today, wday нужно найти и поместить в:

$arr_info[0][$i]


значения td с классом time нужно найти и поместить в:

$arr_info[1][$i]
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 02.07.2013 11:46
$i = 0;
foreach($data->find('span.today') as $today){
$arr_info[0][$i] = $today->innertext;
$arr_info[1][$i++] = $today->next_sibling()->innertext;
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Ibo_Sher
0 # Ibo_Sher 08.07.2013 16:54
Добрый день подскажите как передать в парсер класс, если его имя содержит пробел? Нпример
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 08.07.2013 17:07
я писал об этом a[class=class1 class2]
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Парсер
0 # Парсер 04.01.2015 21:50
Класс не может содержать символа пробела.

Можно искать по одному из классов которые прописаны в атрибуте class.

К примеру


<a href="#" class="class1 class2">Some link</a>

можно найти


$dom->find('a.class1', 0);
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виталий
0 # Виталий 16.07.2013 06:27
Добрый день, встретился с такой проблемой - есть сайт с таблицей в 1й колонке идут картинки, во второй артикул, в третьей текст, необходимо парсить только те картинки у которых во второй колонке идентичный артикул. До этого не занимался подобными вещами, но тут иначе ни как. Уже голова квадратная от всего этого... Буду признателен за помощь!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 16.07.2013 11:43
$today->next_sibling() $today->prev_sibling()
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Андрей
0 # Андрей 29.07.2013 03:22
Спасибо за статью.

Но тем не менее столкнулся с проблемой:

Пробуем парсить html:


<html>
<head>
<title>Тексты песен. Слова к песням, скачать бесплатно музыку в mp3</title>
<meta name="description" content="база текстов песен, слова к песням исполнителей музыки" />
<meta name="keywords" content="тексты песен, текст песни, слова к песне, скачать бесплатно" />
<meta http-equiv=Content-Type content="text/html;charset=windows-1251" />
<meta http-equiv="content-language" content="ru" />
</head>
<body>

<div align="center">

</div>


</body>
</html>




Для этого использую:


function prepareForDOM($html, $encoding) {
$html = iconv($encoding, 'UTF-8//TRANSLIT', $html);
$html = preg_replace('/<(script|style|noscript)\b[^>]*>.*?<\/\1\b[­^>]*>/is', '', $html);
$tidy = new tidy;
$tidy_config = array(
'drop-font-tags' => true,
'drop-proprietary-attributes' => true,
'hide-comments' => true,
'indent' => true,
'logical-emphasis' => true,
'numeric-entities' => true,
'output-xhtml' => true,
'input-encoding' => 'utf8',
'output-encoding' => 'utf8',
'wrap' => 0
);

$tidy->parseString($html, $tidy_config, $tidy_config['output-encoding']);
$tidy->cleanRepair();
$html­= $tidy->value;
$html = preg_replace('#<meta[^>]+>#isu', '', $html);
$html = preg_replace('#<head\b[^>]*>#isu', "<head>\r\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />", $html);

return $html;
}

$answer_m = file_get_contents('newhtml.html');
$answer_m = prepareForDOM($answer_m, 'cp1251');
$html = str_get_html($answer_m);
$lets = $html->find('div');




Два момента интересны:

1. Если не заменять(закоментить prepareForDOM) то выдает ошибку

arning: mb_strpos() [function.mb-strpos]: Offset not contained in string ... on line 1570



2. Даже после предварительной обработки div не находится. $lets - пустая на выходе.



Очень надеюсь на вашу помощь. Сам уже и не знаю что делать - на другую библиотеку что-ли переходить...
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Андрей
0 # Андрей 29.07.2013 10:41
1. - так и не понятно почему так

2. если убрать элемент русский текст из title, то работает нормально, даже если русский текст есть в теле страницы.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 29.07.2013 11:37
похоже великий и могучий ПолтерГейц)))
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
ev-peregudov
0 # ev-peregudov 18.08.2013 22:48
Всё круто. Но возникла проблема. Пытаюсь спарсить содержимое

Форматирование теряется, нет перехода на новые строки. Скажите, пожалуйста, как исправить?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
ev-peregudov
0 # ev-peregudov 18.08.2013 22:51
содержимое тега pre
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
regexp
0 # regexp 27.08.2013 15:41
пример в начале статьи не корректен:
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
regexp
0 # regexp 27.08.2013 15:43
Всю регулярку порезали

'/<a\s+href=”([^”]+)”\s*>(.*?)<\/a>/'
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 27.08.2013 18:40
да? а если юзер добавит вашей ссылке стилей
<div><a style="bla" href="http://xdan.ru"><div>Сайт по программированию парсеров</div><div> и многое другое</div></a></div>


к любому конкретному примеру можно подобрать регулярку, но стоит слегка отойти от это примера и все сломается. simple_html_dom такие перепады не страшны
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Максим
0 # Максим 05.10.2013 05:32
Как правильно работать если страница большая слишком. Мне надо спарсить карту сайта на огромном портале..
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Сергей
0 # Сергей 16.10.2013 21:39
А как парсить много страниц?
Допустим есть сайт site.com
на нем 100 ссылок. И на каждой из тех ссылок еще по 20 ссылок. Получается мне нужно спарсить 2000 страниц в 1 базу. Допустим картинка, описание, телефон.

Второй вопрос: Как парсить только новую информацию на сайте. Например на сайте СМИ обновляются статьи. Я хочу заходить туда раз в сутки(через cron) и забирать только новые статьи в свою базу(а так же если какая то статья из старых обновилась на сайте то ее тоже обновить у себя).

Третий вопрос: Как работать через proxy?

Вообщем хочу для себя создать мощный парсер(с PHP, mysql, HTML работаю давно). Статья лучшая что пока находил по парсерам. НО у меня даже тот пример с Джесикой альбой не получился. Я просто скопировал код и всеравно пустая страница.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 17.10.2013 17:38
Также и парсить. Циклами и рекурсиями, перебирать все ссылки. грузить их в отдельный объект, также распарсивать и их.

Чтобы знать какие статьи у вас новые, надо запоминать старые. Я обычно если парсил статью, в отдельное поле складывал md5(ее урл) потом сравнивал. Если в базе уже есть такой хеш, то не грузил статью.

Через прокси умеет работать curl
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 13:31
добрый день пытаюсь с помощью вашего шаблона сделать парсер для сайта aliexpress.com. но вот на последнем выводе описания почему то не получается вывести

код:

Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 13:32
<?php
require_once 'simple_html_dom.php';

//url poiska//
$link= file_get_html('http://www.aliexpress.com/store/product/Beats-Audio-Original-phone-HTC-ONE-V-T320e-4G-ROM-WIFI-GPS-5MP-3G-GSM-smartphone/901395_1100253986.html');
$html = str_get_html("$link");

//poisk naxvania tovara <h1> na stranice//
if(count($html->find('h1')))
foreach($html->find('h1') as $title)

//udalyaet vse tegi ostavlyaet tolko tekst//
$w=$title->innertext;

//udalyaet nenujnie slova is teksta//
$endtitle=str_replace(array('shipping', 'smartphone', 'mobile', 'Original', 'free', 'phone', 'GSM', '8MP', '5MP', '3.2MP', '2MP', 'GPS', 'WIFI', 'Wifi', 'ROM', 'RAM', '32G', '16G', '8G', '4G', '3G', '2G', '32g', '16g', '8g', '2g', '3g', '4g', 'new', 'unlocked', 'NEW', 'New', 'brand', 'Brand', 'smartphne','internal','cell', 'big', 'sale', 'In stock', 'HK post', 'Camera', 'camera', 'factory', '100%'), '', $w);

//vivod gotovogo teksta//
echo $endtitle.'(UNLOCKED ORIGINAL NEW)';

//poisk i vivod ceni//
if(count($html->find('span[itemprop=lowPrice]')))
{foreach($html->find('span[itemprop=lowPrice]') as $price)
echo '<br>'.$price;}
else{
foreach($html->find('span[id=sku-price]') as $price)
echo '<br>'.$price;
}

//poisk i vivod ceni//
foreach($html->find('h2[class=description]') as $pr)
echo '<br>'.$pr;


?>
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 22.10.2013 17:38
ну по хорошему все же нужно echo $price->innertext;
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 19:39
аа ну да,

а как на счет h2[class=description]?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 22.10.2013 19:53
а откуда вы вообще взяли этот h2? в странице нет такого тега, как и класса description
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 20:30
h2 выводит только Product Description. оттуда начинается описание товара.

"Beats Audio Original phone HTC ONE V T320e 4G ROM WIFI GPS 5MP 3G GSM smartphone free shipping

Product description:



General 2G Network GSM 850 / 900 / 1800 / 1900

3G Network HSDPA 850 / 900 / 2100

SIM Mini-SIM



Announced 2012, February

Status Available. Released 2012, April

Body Dimensions 120.3 x 59.7 x 9.2 mm (4.74 x 2.35 x 0.36 in)

Weight 115 g (4.06 oz)

Display Type Super LCD2 capacitive touchscreen, 16M colors

Size 480 x 800 pixels, 3.7 inches (~252 ppi pixel density)

Multitouch Yes " и т.д.



как вывести именно это описание до картинок? после этого описания выходят картинки.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 22.10.2013 20:44
понял наконец. не внимательно читали
echo $html->find('h2[class=description]',0)->next_sibling()->innertext
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 20:51
спасибо за быстрый ответ, до все равно не отображает. выдает пустоту.(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 21:19
данный код выдает ошибку :

"Fatal error: Call to a member function next_sibling() on a non-object in Z:\home\test1.ru\www\index.php on line 32"

32 линия и есть эта линия что вы написали.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 22.10.2013 21:27
зачем
$link= file_get_html('...'); 
$html = str_get_html("$link");


когда достаточно
$html= file_get_html('...');


во сторых в html похоже ошибка, и найти он его не может. h2.desc... нет в дом. Парсите этот кусок регуляркой. только не спрашивайте какой.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 19:40
h2[class=description] никак не отображает нужную информацию, а вроде все правильно делаю....
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Armen
0 # Armen 22.10.2013 19:45
вообще то надо вывести описание которое после h2[class=description] идет тоже. т.е. получается div[id=custom-description]
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Hrefs
0 # Hrefs 08.11.2013 00:44
Подскажите, как сделать выборку, если на нужной мне странице стоит тег:

<td class="alt1" colspan="2">


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

Например я делаю так:

foreach($html->find('td[class="alt1" colspan="2"] ') as $element1) 
echo $element1;


Но ничего не выводится

А если делать так:

foreach($html->find('td[class="alt1"] ') as $element1) 
echo $element1;


то выводится ненужный мне текст, так как тег
<td class="alt1">
встречается на странице несколько раз.

Вариант с указанием позиции тега так:

foreach($html->find('td[class="alt1"] ', 2) as $element1) 
echo $element1;


тоже не подходит, так как нужный текс может встречаться на страницах под разной позицией.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Hrefs
0 # Hrefs 08.11.2013 00:52
Предыдущий пост коряво отобразился

Подскажите, как сделать выборку, если на нужной мне странице стоит тег:



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

Например я делаю так:

foreach($html->find('td[class="alt1" colspan="2"] ') as $element1)

echo $element1;

Но ничего не выводится

А если делать так:

foreach($html->find('td[class="alt1"] ') as $element1)

echo $element1;

то выводится ненужный мне текст, так как тег встречается на странице несколько раз.

Вариант с указанием позиции тега так:

foreach($html->find('td[class="alt1"] ', 2) as $element1)

echo $element1;

тоже не подходит, так как нужный текст может встречаться на страницах под разной позицией.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 08.11.2013 02:18
foreach($html->find('td[class="alt1"] ') as $element1)
if( $element1->colspan="2" ){
echo $element1;
break;
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Hrefs
0 # Hrefs 08.11.2013 05:15
Спасибо, но все равно отображается не то что нужно.

Вот пример html кода http://i-css.ru.s3.hhos.ru/example.txt

Там только один раз встречается тэг
<td class="alt1" colspan="2">


И нужно спарсить сразу то что следует за ним:
<span class="smallfont"><a href="member.php?u=37470">RixerBox</a>, <a href="member.php?u=32875">Bloomer</a></span>


Но ничего не выходит :(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Hrefs
0 # Hrefs 09.11.2013 19:30
UPD: уже нашел решение, регулярным выражением оказалось проче чем с использованием Simple-HTML-DOM
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
barbarisa
0 # barbarisa 31.12.2013 00:56
На редкость качественный материал. Спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Замонбек
0 # Замонбек 08.01.2014 03:48
добрый вечер друзя !

Я хочу парсит сайт ism.uz но столькнуля проблемой не ругайтес ёще я новичок в этом деле ))

Например я хочу парсит страницу http://ism.uz/letter/f/ ну там много ссылок,как парсит эти ссылки? ато не хочу войти каждуйу ссылку и парсит ))
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
DarkBioloG
0 # DarkBioloG 14.02.2014 16:55
А как можно спарсить параметр "herf" из тега "a" чтобы он был в формате URL?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Арсен
0 # Арсен 04.03.2014 23:29
А как парсить пагинацию, например есть лишка с классом "current", нужно достать следующею лишку. Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Навка
0 # Навка 16.03.2014 05:06
Да продлятся твои дни, добрый человек! И только здесь я нашла как именно подключать эту библиотеку! Везде пишут -подключите... Спасибо еще раз!!!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Навка
0 # Навка 16.03.2014 05:43
Спасибо!! только здесь нашла, как именно нужно подключать это либу! Нигде не могла найти)) И весь урок супер, спасибо!!!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Navka
0 # Navka 30.03.2014 06:18
Спасибо за статью))) очень полезно и просто. Остался один вопрос. Вы пишите: "Думаю никому в здравом уме, не придет в голову парсить Яндекс с помощью file_get_content." Поэтому собственно и вопрос: а чем надо парсить поисковики? И почему file_get_content не катит?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 30.03.2014 15:36
поисковики, как и многие умные сайты предпочитают работать не с ботами а с живыми людьми. поэтому проверяется все: наличие кукиес, реферал, операционка, версия браузера, разрешение экрана, некоторые даже анализируют поведение пользователя на странице. Для одного, особо умного сайта, мне пришлось изображать с помощью js на сайте некую деятельность. Прокрутку экрана. По ссылкам парсер не просто переходил а кликал на них.

Большинство сайтов можно спарсить с помощью curl однако в более сложных случая приходится эмулировать браузер (IE COM PHP) или других хитрых методов
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Denis
0 # Denis 04.04.2014 14:36
Здравствуйте. Прежде всего хочу сказать огромное спасибо за очень полезную и качестаенную статью.

Я новичек в php и вообще в программировании в целом, меня всегда интересовал этот вид ТВОРЧЕСТВА и сейчас мне необходимо сделать парсер который удовлетворял бы моим требованиям и спомощью данной статьи я боюсь что это у меня получится.

Собственно вопрос заключается в следующем.

мне необходим парсер каторый мог бы забирать
<iframe>
теги из
id="mediaEmdebCodeInput"
например с xvideos[dot]соm с помощью метода find. Хотелось бы узнать правельный ли у меня ход мысли или это лучше реализовать с посощью других методов. Еще раз Большое спасибо за статью и заранее благодарю Вас за ответ.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Сергей
0 # Сергей 06.05.2014 09:36
Здравствуйте, добрый Человек!

Я новичок, поэтому не серчайте, пожалуйста! :)



Не могли бы Вы подсказать, как получить данные в следующем примере:



Есть таблица:

<table width=820 cellspacing=1 cellpadding=3 border=0>


<tr bgcolor="#C0C0C0" align=right>
<td>Проход</td>
<td>Прибыль</td>
<td>Всего сделок</td>
<td>Прибыльность</td>
<td>Матожидание</td>
<td>Просадка $</td>
<td>Просадка %</td>
</tr>

<tr align=right>
<td title="данные 1">номер строки 1</td>
<td class=mspt>Прибыль строки 1</td>
<td>Всего сделок строки 1</td>
<td class=mspt>Прибыльность строки 1</td>
<td class=mspt>Матожидание строки 1</td>
<td class=mspt>Просадка $ строки 1</td>
<td class=mspt>Просадка % строки 1</td>
</tr>


<tr align=right>
<td title="данные 2">номер строки 2</td>
<td class=mspt>Прибыль строки 2</td>
<td>Всего сделок строки 2</td>
<td class=mspt>Прибыльность строки 2</td>
<td class=mspt>Матожидание строки 2</td>
<td class=mspt>Просадка $ строки 2</td>
<td class=mspt>Просадка % строки 2</td>
</tr>

</table>



Есть код, которые не работает к сожалению, а по идее должен был бы работать, но, видимо, я ошибаюсь в чем-то, а в чем понять пока не могу:


include("simple_html_dom.php");
$file = 'OptimizationReport.html'; //тут находится таблица

$html = str_get_html($file);


foreach($html->find('tr') as $k => $tr)
{
foreach ($tr->find('td') as $kk => $td)
{
$array[$k][$kk] = $td->plaintext;
}
}




в массив ничего не заносится к сожалению.

Не могли бы подсказать, что не так делаю?



Благодарю!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Сергей
0 # Сергей 06.05.2014 09:37
Ой, прошу прощения, 2 раза отправилось...
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 06.05.2014 12:06
­str_get_html($file); // берет данные из строки.

Вам нужна file_get_html как минимум
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Maxim
0 # Maxim 18.05.2014 15:56
А что делать, если атрибут class содержит пробелы??
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 19.05.2014 11:11
вопрос уже поднимался. find('class="class1 class2"')
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
HiPutler
0 # HiPutler 02.06.2014 18:59
Насколько подобный метод парсинга нагружает сервер-донора, учитывая то что парсится множество страниц в цикле? Обязательно ли прибегать в таком случае к мультипотокам и прокси?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 02.06.2014 22:41
можно поставить паузу между парсингом
sleep(3)//задержка на 3 секунды
мультипоточный парсинг описан здесь прокси использовать по необходимости, если сервер жестко режет все по ip, в большинстве серьезных кантор это не так. банят по умному, эвристически
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
HiPutler
0 # HiPutler 03.06.2014 08:25
Вот спасибо большое добрый программист. И за статью и за совет.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
DemonIa
0 # DemonIa 16.07.2014 18:14
Всем привет. Подскажите, почему вот такой код:
foreach($html->find('a[href*=http]') as $link)
echo $link.'
';
возвращает объект? Я же нигде не указывал индексы, т.е должен быть массив. Мне нужно результат работы парсера записать в csv файл, а функция fputcsv, что очевидно, не может принимать объект. Как быть? Спасибо
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Boarworm
0 # Boarworm 26.07.2014 17:32
Добрый день, решил сделать бота для сайта накрутки лайко, подписчиков и т.д. Авторизацию проходит нормально, заходит на нужную страницу. Далее нужно перейти по ссылке на которой нужно ставить лайк, ссылка вида http://vk.com/............. Я так понимаю нужно спарсить ссылки такого вида, а потом переходить по ним. Пробую так:
$data  = ­file_get_html('http://site.com/user/likes/');
но парсится страница http://site.com/ Может нужно куки как-то передавать?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Dmitriy
0 # Dmitriy 03.08.2014 01:28
Здравствуйте! А подскажите, как парсить сайт, требующий регистрацию? У меня есть логин пароль, но парсер то зайти через них не может, как быть?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 03.08.2014 20:30
http://xdan.ru/avtorizacija-na-sajte-pri-pomoshhi-curl-php.html
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Валера
0 # Валера 29.08.2014 19:30
а как строить большой массив? я например хочу взять все ссылки из меню как главные категории и сохранить? затем к этому массиву добавить элементы?

я пробую

$rated = array();

$main_cats = $html->find('.big_menu a');

$rated['main_cats'] = $main_cats;

print_r($rated);

у меня какая-то жесть выводится а не мой массив
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 29.08.2014 21:20
$rated['main_cats'] = array();
foreach($­data->find('.big_menu a') as $a)
$rated['main_cats'][] = $a->href;
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Валера
0 # Валера 29.08.2014 20:04
и еще, пытаюсь добраться до всех li

http://imagizer.imageshack.com/img538/5411/R6gpci.png



foreach($data->find('div.top_menu div.inner ul') as $ul)

{

foreach($ul->find('li') as $li)

{

echo $li;

}

}



но ничего не находит
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 29.08.2014 21:21
в указанном коде все верно, ищите ошибку выше
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Andrew
0 # Andrew 03.09.2014 14:44
Добрый день!

Спасибо за ваш сайт, нашел много полезного.



В парсинг окунулся пару дней назад, знаний мало.

Я спарсил таблицу:

require('simple_html_dom.php');
$html = file_get_html('http://test.com/');
$table = $html->find('table', 0);
$rowData = array();

foreach($table->find('tr') as $row) {
$flight = array();
foreach($row->find('td') as $cell) {
$flight[] = $cell->innertext;
}
foreach($row->find('th') as $cell) {
$flight[] = $cell->innertext;
}
$rowData[] = $flight;
}

echo '<table>';
foreach ($rowData as $row => $tr) {
echo '<tr>';
foreach ($tr as $td)
echo '<td>' . $td .'</td>';
echo '<td>' . $th .'</td>';
echo '</tr>';
}
echo '</table>';



В таблице присутствуют ссылки. От них мне нужно избавится.

Когда ставлю вместо innertext - plaintext, то ссылки уходят, но так же уходят и картинки, которые присутствуют в таблице, поэтому такой вариант не подходит.



Прошу помощи, заранее спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Фототехник
0 # Фототехник 09.09.2014 03:36
Можно просто убрать ссылки через css
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Andrew
0 # Andrew 15.09.2014 21:57
Как?

Подскажите, пожалуйста!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 16.09.2014 19:15
Это он глупость сказал, в ветке ниже есть пример удаления тега h2, замените на a и будет вам счастье
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Фототехник
0 # Фототехник 19.09.2014 00:55
Ну почему же, просто не так выразился*, ссылку можно скрыть с помощью css, Часто так делают на бесплатном хостинге который принудительно вставляет ссылку рекламы.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Andrew
0 # Andrew 22.09.2014 14:17
Извиняюсь, но можете написать готовый код?) Буду очень благодарен!)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 22.09.2014 18:28
foreach($data->find('a') as $a){
$a->outertext = ­'';
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serg47
0 # serg47 09.09.2014 02:09
помогите пожалуйста. Есть такой кусок:

<div class="slide-content">
<h2 class="slide-title"><a href="http://myautumn.ru/pesni/ohochinskij-yurij-dozhdlivyj-london.html" title="Permalink to Охочинский Юрий &#8212; Дождливый Лондон" rel="bookmark">Охочинский Юрий &#8212; Дождливый Лондон</a></h2>Вот и в Лондон нагрянула осень! Все укрыл бесконечный туман. Ветер листья куда-то уносит. За душой любовь и обман.</div>

Подскажите как выбрать текст после закрывающего тега</h2>?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 09.09.2014 13:19
удалить h2, потом дернуть то, что осталось
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serg47
0 # serg47 10.09.2014 02:17
Спасибо за ответ!


include 'simple_html_dom.php';
$data = file_get_html('http://yyyyyyu.ru');
foreach($data->find('.slide-content') as $main){
$b=$main->find('h2');
$b->outertext = '';
echo "$main->plaintext";
}


Пытаюсь так, но не получается. Пните в нужном направлении! Заранее спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serg47
0 # serg47 10.09.2014 16:14
Если кому интересно "докумекал" рабочий вариант :


include 'simple_html_dom.php';
$data = file_get_html('http://myautumn.ru');
foreach($data->find('.slide-content') as $main){
$b=$main->find('h2',0);
$b->outertext = '';
echo $main->innertext.'<br /><br />';
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
RomHunter
0 # RomHunter 17.09.2014 13:47
Отличная статья, спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
blackx1
0 # blackx1 19.09.2014 00:58
Спасибо, хорошая статья

Только вот интересно когда такой случай

Когда есть к примеру " <b>Название: </b>Название1<br />"

Как вытянуть "Название1"?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 19.09.2014 11:37
К сожалению никак, через библиотеку этого не сделать. Нужно как-то брать корневой для этих тегов элемент и уже анализировать его содержимое через регулярные выражения. Вообще, для парсинга хоть я и написал, что регулярки не очень удобны, но в отдельных случаях они незаменимы.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
irirni
0 # irirni 27.09.2014 23:00
Спасибо за статью!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Oleg
0 # Oleg 29.09.2014 14:12
Добрый день! Спасибо за библиотеку. Немного разобраться не могу в ней. Требуется из примерно такого хтмл кода дернуть нужный текст и нужные ссылки

<div id="bar"><ul>

<li><a href="/zakon/2014/">не нужная ссылка 2014</a></li>

<li><a href="/">не нужная ссылка</a></li>

<li><a href="/zakon/">не нужная ссылка</a></li>

<li><a href="/catalog/">не нужная ссылка</a></li>

<li><a href="/forum/">не нужная ссылка</a></li>

</ul></div>

<div><a href="/info/423/">нужная ссылка</a></div>

<div>нужный текст</div>

<div>нужный текст</div>

<div style="margin-top: 10px"></div>

<div><a href="/info/472/">нужная ссылка</a></div>

<div>нужный текст</div>

<div>нужный текст</div>

<div style="margin-top: 10px"></div>

<div><a href="/info/732/">нужная ссылка</a></div>

<div>нужный текст</div>

<div>нужный текст</div>

<div style="margin-top: 10px"></div>



в пхп прописываю так:

$data_ooo = file_get_html($arr_city[27]);
if($data_ooo->innertext!='' and count($data_ooo->find('a'))){
foreach($data_ooo->find('a') as $c){
$b = $c->find('li,ul',0);
$b->outertext = '';
//$data_ooo->innertext;
echo '<a href="http://www.vutil.ru'.$c->href.'">'.$c->plaintext.'</a></br>';
//echo $c->innertext;
}
}




но что то не выходит, помогите плиз!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Парсер
0 # Парсер 04.01.2015 21:47
Прочитайте про DOM и HTML.

Вы сначала получаете список тегов <a>, а потом в них ищете <li> хотя в HTML которые вы привели в качестве примера во всех тегах <a> только текст.



Смысл самого кода написанный вами непонятный.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Сергей Пил
0 # Сергей Пил 29.11.2014 10:39
Здравствуйте написал вот такой парсер.


<?php
//ставим лимит памяти больше, т.к. библиотека затратна к ресурсам
ini_set('memory_limit', '128M');
//так же ставим больше время сессии
set_time_limit(800);
//начинаем сессию
session_start();
require_once 'simple_html_dom.php';
$data = new simple_html_dom();
$data = file_get_html('http://www.mon.gov.ua/ua/news');
if($data->innertext!='' and count($data->find('aside#leftSideBar'))){
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Тег А, атрибут target</title>
</head>
<body><?
foreach($data->find('div.standartBlock') as $aside){
$aside = preg_replace("/[\n\r\t]/", '', $aside); // замена символов перевода строки и табул¤ции на пробел
$aside = preg_replace("/[ ]{2,}/", '', $aside); // замена более 2х пробелов на один

$div ='<div class="data">';// готовим для даты подмену шаг 1
$div1 ="</div>";// готовим для даты подмену шаг 2
$today = $div. date("d.m.y"). $div1;// готовим для даты подменушаг 3
$aside = preg_replace('/\<span class\="date"\>(.+)\<\/span\>/is', $today, $aside);// замена класса даты на текушюю
$aside = preg_replace('/\<div class\="standartBlock stBlockBlue\">(.+)\<\/div\>/is', '', $aside);
$aside = preg_replace('/\<div class\="image\">(.+)\<\/div\>/U', '', $aside);
$aside = str_replace('<span>', '', $aside);
$aside = str_replace('</span>', '', $aside);
$domain = "http://www.mon.gov.ua";
$new = preg_replace('#(<a href=")(.*)(">)#', "$1$domain$2$3", $aside);


echo $new;
}
}
//освобождаем ресурсы
$data->clear();
unset($data);
?>

Всё в роди нормально, но хочу чтобы можно было указывать определённое количество новостей, кто знает подскажите пожалуйста.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Елена
0 # Елена 11.12.2014 15:48
Не пойму что делаю не так.


ini_set('display_errors', 1);
ini_set('mbstring.func_overload', 0);

// example of how to use basic selector to retrieve HTML contents
include($_SERVER['DOCUMENT_ROOT'].'/simple_html_dom.php');


// get DOM from URL or file
$html = file_get_html('http://yandex.com/images/search?text=%22odeonlight%22+2553%2F7+ODL13+004+%D0%B1%D1%80%D0%BE%D0%BD%D0%B7%D0%B0+%D0%9B%D1%8E%D1%81%D1%82%D1%80%D0%B0++E14+7*40W+Rika&itype=&nojs=1&rpt=image&tld=com');


/*echo '<pre>';
print_r($html);
echo '</pre>';*/

$ret = $html->find('img');
echo '<pre>';
print_r($ret);
echo '</pre>';

В переменной $ret ноль. Я ставила другие теги. Так же всё по нулям. Точнее ищет только html тег
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Парсер
0 # Парсер 04.01.2015 21:39
Вы сами перейдите по той ссылке что указали в


$html = ­file_get_html('http://yandex.com/images/search?text=%22odeonlight%22+2­553%2F7+ODL13+004+%D0%B1%D1%80%D0%BE%D0%BD%D0%B7%D0%B0+%D0%9B%D1%8E%D1­%81%D1%82%D1%80%D0%B0++E14+7*40W+Rika&itype=&nojs=1&rpt=im­age&tld=com');

Вообще блок с картинками отдается AJAX запрсом, поэтому тут таким простым подходом не ограничишься.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Парсер
0 # Парсер 04.01.2015 21:37
В своем коде я так же чищу и полученные элементы, к примеру


$a->clear();

потому что из-за них память тоже засоряется
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
VASILIYYY
0 # VASILIYYY 26.02.2015 01:23
Отличная статья! Скажите, а если при получении html страницы она очень велика - несколько миллионов символов, библиотека просто отказывается ее обрабатывать, какие есть варианты решения проблемы? При этом если получать страницу курлом и сразу кидать ее на вывод, она выводится, так что дело именно в simple html dom. Спасибо.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
+1 # Leroy 26.02.2015 07:44
как вариант выдирать регуляркой нужный кусок текста и уже его скармливать библиотеке.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Валерий
+1 # Валерий 26.02.2015 05:44
Полезная статья! А не подскажите, можно ли из элемента код распарсить код, либо получить значение конкретной переменной этого скрипта (основная цель этого упражнения)?
К примеру, на загружаемой странице есть скрипт ниже:

var flashvars = {
uid: 'videoplayer',
file: 'http://',
poster: 'http://...jpg',}
var params = {
bgcolor: '#000', ...}

$html = file_get_html('http://пример.php'); //Загружаю страницу
foreach($html->find('script') as $element) //парсю все скрипты
echo $element->plaintext . ''; //а дальше не знаю как вывести код скрипта, либо вывести значение переменной flashvars:file
Можно ли такое проделать с этим парсером?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Валерий
0 # Валерий 26.02.2015 05:47
*речь об элементе < s c r i p t > код < / s c r i p t >
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 26.02.2015 07:47
нет. содержание элемента это не задача этой библиотеки. Содержание нужно распарсивать уже регулярным выражением, т..е. в вашем случае примерно так
if(preg_match('#file:'(.*)',#Uus', $element->plaintext, $list)) {
echo $list[1];
}
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Валерий
0 # Валерий 26.02.2015 08:01
Спасибо за ответ! Да, похоже только регулярными выражениями можно распарсить содержание скрипта и выдернуть значение переменной.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
cookie
0 # cookie 11.03.2015 20:41
Я не понял как соединять результаты ответов, в плане, что я хочу одним скритом найти ссылку, а уже потом парсить информацию по этой ссылке. Мне выкидывает ошибку. Что делать?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Andrey
0 # Andrey 14.03.2015 03:56
Спасибо Вам огромное!

У меня вопрос:

Можно ли в выборке попросить чтобы название класса начинолось на x и кончалось на y?

Что-то вроде этого:

div[class^=x && $=y]
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
campusboy
0 # campusboy 14.03.2015 08:52
Я новичкок, возможно, глубоко не смог разобраться, но эта библиотека не дала мне решения в задаче. Были на сайте блоки DIV, у которых был класс типа text_523547. Мне нужно было не только парсить текст внутри блоков, но и сохранять в базу вот это число именно. Библиотекой не смог, сделал на регулярках. И ещё не понравилось. К примеру, на странице есть одна ссылка, я нахожу её библиотекой и помещаю в переменную. Потом через var_dump хочу посмотреть, что внутри. В общем, 4ГБ моей ОЗУ оказалось недостаточным, чтобы просмотреть на экране через ХРОМ, что же есть внутри. Там куча хлама. А для новичка важно наглядно видеть, что внутри переменной, чтобы потом оперировать с данными. В итоге, регуляркой решил вопрос (и удобно смотреть что внутри переменных), плюс она работает в среднем 0,5 секунды, когда библиотека в среднем 0,7-1сек.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Дмитрий Николаев
0 # Дмитрий Николаев 22.04.2015 15:42
Добрый день,очень буду благодарен если толкнете в правильном направлении реализации задуманного.
Есть сайт с авторизацией,авторизированому пользователю доступен контент на определенной странице этого сайта,часть этого контента автоматически обновляется 1 раз в час,необходимо разместить часть этого контента на странице другого сайта с теми же функциями автоматического обнавления.

Хожу вокруг да около,вроде рядом,но не могу понять как реализовать.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 23.04.2015 09:44
Вот тут http://xdan.ru/avtorizacija-na-sajte-pri-pomoshhi-curl-php.html почитайте. То что вам нужно
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Andrey
0 # Andrey 14.08.2015 03:25
Добрый день, а можно ли запарсить атрибут style?

Пробовал так:


$bgPos = $digit->getAttribute('style');
echo $bgPos. '';


И так:
echo $digit->style . '';


Почему то не вышло(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 14.08.2015 11:30
и первый и второй вариант верны, ищите ошибку где-то выше
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Владимир М
0 # Владимир М 24.08.2015 10:23
Есть ресурс http://rabota.e1.ru/vacancy?rubric[]=50 который при парсинге вакансий ничего не отдает, хотя http://rabota.e1.ru выдает все номально.
Код:


При обработке выдает ошибку:
Fatal error: Call to a member function find() on a non-object in C:\OpenServer\domains\localhost\index.php on line 5

Как я понимаю в следствии пустого обьекта.
Прошу помочь составить запрос.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
kuller
0 # kuller 24.09.2015 21:24
Не могу чета понят. Помогите разобраться. Допустим код из примера который парсит картинки выводит их на страницу, а если надо каждой картинке спарсит еще описание, как это сделать? Что только и не пробовал сделать. Сейчас вот такой вид

foreach($data->find('h2.zagolovki') as $txt)
{
$htmls = $txt->innertext;

$a++;
if($a>$n)break;
}

foreach($data->find('div.shortimg a img') as $img)
{
$arr = explode("/", $img->src);

echo $htmls.'';

$i++;
file_put_contents('uploads/'.($arr[5]).'.jpg', file_get_contents($img->src));
if($i>$n)break;
}

результат работы, для каждой картинки берется одинаковый заголовок. Что не так?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виктор Назаров
0 # Виктор Назаров 30.10.2015 20:02
Подскажите, а как заменить ссылку, оставив текст
например Игры онлайн как заменить http://igroflot.ru/ на http://site.ru?
К сожалению php не знаю, а в комментариях похожего случая не было.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виктор Назаров
0 # Виктор Назаров 30.10.2015 20:28
К сожалению html не отобразилось, вот пример:
  • Игры онлайн как заменить http://igroflot.ru/ на site.ru?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Виктор Назаров
0 # Виктор Назаров 30.10.2015 20:30
a href = "igroflotru/" >Игры онлайн
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 03.11.2015 14:15
http://php.net/manual/ru/function.str-replace.php
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Vladimir
0 # Vladimir 22.12.2015 15:10
Помогите спарсить отсюда http://101.ru/?an=personal_playlist&userid=489993

Самое верхнее название исполнителя и трэка, вот часть из кода:

Цитата:



KEIFER, Tom - Blue Christmas
Отсюда нужно забрать "KEIFER, Tom - Blue Christmas"

Спасибо!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Vladimir
0 # Vladimir 22.12.2015 15:12
Код некорректно отобразился:




KEIFER, Tom - Blue Christmas


из этого нужно забрать "KEIFER, Tom - Blue Christmas"
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
АлександрАнатольевич
0 # АлександрАнатольевич 29.01.2016 23:15
Спасибо огромное! Очень помогло)
Было бы интересно увидеть настолько же подробный мануал по парсингу сайтов с защитой.
Может быть есть готовые библиотеки с эмуляцией браузера? Наподобие зеннопостера только на PHP
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александрqazzzqsa
+1 # Александрqazzzqsa 31.01.2016 21:56
Как найти элемент по тексту между тегами? Например Employment type
Пробовал
$html->find([text()='Employment type'])
$html->find('Employment type')
не получается(
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
jkeksa
0 # jkeksa 31.03.2016 08:08
Спасибо, но все же регулярками иногда прощще найти что-то..
Часто надо выдернуть какой-то контент из текста, хотя по ДОМу лазиить лучше конечно селекторами.
С другой стороны.. оба этих метода легко крошатся при модификациях страниц.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 01.04.2016 09:10
ну лазить по дому все же надежнее и при модификации страницы селекторы поправить проще. Можно их в конфиге парсера к примеру все держать. С регулярками так тоже можно, но так вот просто не поправишь, надо тестить, смотреть окружение. Проверить под все ли случаи подходит.
А так да, я совмещаю и регулярки и дом. Если нужно выдернуть одно единственное значение то конечно лучше регулярки
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Евгений
0 # Евгений 19.07.2016 17:25
никто не подскажет в чем ошибка ? переменная $zz нече не парсит
Код: foreach($html->find('#allEntries') as $a){
$jj = $a->plaintext;
$zz = $a->find('.vnewtop')->plaintext;
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Ivan26ru
0 # Ivan26ru 09.08.2016 01:03
Цитирую Евгений:
никто не подскажет в чем ошибка ? переменная $zz нече не парсит
Код: foreach($html->find('#allEntries') as $a){
$jj = $a->plaintext;
$zz = $a->find('.vnewtop')->plaintext;


find('.vnewtop') ищет все элементы с классом vnewtop, и добавляет в массив, а plaintext выводит чистый текст уже для конкретного элемента.
Решение:
$zz = $a->find('.vnewtop');
foreach($zz as $zzz){
echo "Тест zzz: " . $zzz->plaintext;
}

примерно так, но могу и ошибаться)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Александр8839
0 # Александр8839 22.08.2016 23:13
$img = $data->find('img', 0);
$img_src = $img->src;
echo $img_src->outertext;
Почему не работает? Пишет: Trying to get property of non-object in
Хочу заменить урл в src на свой, как это сделать?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 23.08.2016 07:21
$img_src это просто текст, зачем вы к нему образщаетесь $img_src->outertext
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
campusboy
0 # campusboy 02.09.2016 02:51
Долго - это сколько?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Андрей64646464646464
0 # Андрей64646464646464 18.09.2016 09:10
Явно автор забыл про новичков... Ну да, зачем вообще что то обьяснять, когда можно показать на сколько ты крутой и все и так понимаешь... Что, откуда и куда не понятно. Даже тратить время не буду. Задрали со своими гавносайтами! Учитесь обьяснять и разжовывать!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Leroy
0 # Leroy 20.09.2016 09:21
)))) а вы наверно денег хотите заплатить за разжевывание?)) А то как-то непонятно, автор потратил время, написал статью, а вы даже спасибо не удосужились написать.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
campusboy
0 # campusboy 04.10.2016 16:22
Ну хоть время для выливания говна у тебя хватает. Жаль вот время на разбор примеров его нет.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Drop
0 # Drop 04.10.2016 16:18
Сделал такой парсер.
$link = $_POST['page'];

include('simplehtmldom/simple_html_dom.php');
$html = file_get_html('http://weplay.tv/csgo/tournaments');
$rated = array();

foreach($html->find('td') as $t1)
echo $t1->plaintext;
#print_r($rated);
$html->clear();
unset($html);
хочу спарсить таблицу. Но класс есть только у первого и последнего столбца. Как сделать так, чтобы парсились только те строки, у которых в 5 стобце класс status complete ?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Женя
0 # Женя 10.11.2016 19:24
Всем привет , поделитесь опытом как можно при помощи этой библиотеки пропарсить все страницы сайта пример или пошагово ? то есть насколько я понимаю начинаем искать ссылки на страницах и переходим по этим ссылкам но не совсем понятно как избавится от дублей и ссылок на другие сайты
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 01.06.2017 11:29
Составляешь массив ссылок, при добавлении новой записи проверяешь есть запись ссылка или нет. Ссылки на другие сайты опять же проверкой строки, отризаешь через php название сайта и проверяешь тот сайт или нет. Другое дело непонятно когда нужно остановить процесс сканирования, таймер какой ни будь поставь что бы не зависло)
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 24.05.2017 13:10
Помогите пожалуйста разобраться в вопросе возможностей curl.
Есть сайт http://game-tournaments.com/dota-2/prodota-cup-sea-8 Заходя на сайт через curl он видит уже нарисованную страницу, на сайте можно переключать букмекера представляющего коэффициенты тогда идет POST запрос на ajax и потом в php обрабатывается запрос и отрисовываются новые коэффициенты без перезагрузки страницы. К сожалению curl видит только начальную страницу, возможно ли как то сделать так что бы curl заходил на страницу менял переключатель и только потом забирал страницу? пробовал генерировать curl с POST запросом без успешно, видимо форма его не отлавливает там. Подскажите направление к решению если оно конечно есть.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
igorroi
0 # igorroi 09.06.2017 13:50
Добрый день!
Написал мини-парсер по данной статье, но очень много времени занимает обработка одной ссылки (3-4 секунды). Это нормально или я что-то делаю не так?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Олежка
0 # Олежка 29.06.2017 08:03
Здравствуйте. Подскажите как спарсить структуру которая открывается по клику ?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 06.07.2017 08:07
Надо смотреть сайт, что именно срабатывает при нажатии, либо там POST, GET запрос идет на сервер и сервер отрисовывает вам данные после клика, или JS скриптом просто спрятано что то.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
vlad
0 # vlad 08.08.2017 11:26
если я делаю $data->find('text') то как мне исключить тексты в h1 и title из этой выборки?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 08.08.2017 17:57
Если там возвращается только текст без тега в коде то ни как. Самый простой вариант пробежаться по всему дереву и убадить весь текст с тегом h и title, что то типо $newdata=$data->find('h')->outertext='' Делать это через цикл. Еще можно помучится с проверкой тега у див элемента, не знаю работает такое или нет, типо h1['class'!=title], надо смотреть искать за что зацепиться.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
vlad
0 # vlad 09.08.2017 16:57
как делая find('text') исключить текст тегах script и style?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
vlad
0 # vlad 16.08.2017 08:59
делаю
для https://zanimayonlayn.ru/mikrokredity/chestnoe-slovo.php
$data = file_get_html($url);
результат при попытке искать в $data Call to a member function find()
не создало объект
почему?

кривой html код ?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 16.08.2017 09:20
html не может получить данные с файла php, делайте file_get_contents
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serg
0 # serg 28.08.2017 01:59
Подскажите как сделать задержку парсинга? не знаю как правильно объяснить.... делаю парсер объявлений и как я понимаю если выполнить скрипт парсинга, тогда пойдет сразу сохранение всех объявлений.... а как сделать чтоб сохранения были поочередно т.е. сохраняем одно объявление, после идет задержка например 30 сек. и потом сохранение второго объявления и так далее. Если я просто пропишу sleep будет ли тот результат который требуется или это надо как та уже в связке js писать?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
+1 # Max 28.08.2017 10:12
Не совсем понятно что вам нужно. Если сохранение данных в вашу бд, то можно сделать как угодно, если же вы хотите каждое объявление вытаскивать с сайта через 30 секунд тогда нужно в цикле делать новый конект к сайту и искать следующее объявление. За один конект curl вытащит весь сайт и контролировать по скорости как он должен парсить сайт вы не сможете. Только делая новый конект допустим через тот же sleep. Не понятно зачем вам это на самом деле.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
serg
0 # serg 28.08.2017 16:51
если вытаскивать сразу все объявления с сайта идет соотвествено большая нагрузка. Так же может выдать ошибку и за не хватки времени выполнения скрипта. В других парсерах на сколько я помню чтоб этого не происходило делают небольшую задержку после каждого сохраненного объявления.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 29.08.2017 10:24
С чего вы взяли что идет нагрузка на сайт с которого вы берете данные? Там ровно такая же нагрузка как если бы вы зашли на эту страницу с браузера (по сути curl эмитируется ваш браузер, забирает dom дерево), другое дело если вы сразу вытаскиваете кучу страниц, или делаете какие ни будь редиректы с одной страницы на другие страницы где находятся другие объявления, тогда в коде уже можно написать функцию задержки при редиректе. Если же страница одна, тогда нагрузка у вас идет при сохранении на ваш собственный сервер, работа с DOM деревом может занимать много времени если алгоритм достаточно сложный, но это опять же на совести самого программиста, как написан алгоритм.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Max
0 # Max 29.08.2017 10:30
Если уж времени не хватает попробуйте функцию CURLOPT_TIMEOUT, у меня есть сайты с которых данные загуржаются более минуты и библиотека отлично с такими объемами справляется. Если не поможет, тогда делайте новый конект в цикле, допустим нужно сделать редирект на страницу с новыми объявлениями, обновляйте конект к новой странице.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
ivanov.ivan
-1 # ivanov.ivan 11.12.2017 18:20
Здравствуйте. Большое спасибо за статью. Очень познавательно.
Есть вопрос: есть сайт, просит логин и пароль для входа и только потом дает нужную мне страницу.
Как это автоматизировать разобрался, curl помог, получаю следующую страницу с нужным мне контекстом.
На этой второй странице есть список, при изменении которого меняются данные страницы.
Страницу с этим списком в переменную получаю. Поиском foreach($html->find("select")as $s) успешно этот список нахожу. Но не могу понять как заставить его изменить значение.....
В отладчике chrome все просто:
1) var mlist = $$("select")
2) mlist[0].value='нужное мне значение'
3) mlist[0].onchange()
и я попадаю на нужную мне статистику, но это в консоли chrome, а как сделать пукнт 2 и 3 через php ?
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Дми-трий
-1 # Дми-трий 11.06.2019 10:35
Добрый день ! Подскажите такую штуку - кладу папку с этим парсером и всеми его файлами, а как их подключить из другой директории ?

Если я кладу файл "simple_html_dom.php" в корень, то все работает, если кладу его к примеру в common/parser то получаю "пустую страницу" без контента

Т.е. я так понимаю что файлы плагина между собой как то связаны "путями" или как то "завязаны" на корне сайта

Пример boogiwoo.ru - внизу парсятся отзывы с вк
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
R7KD
-1 # R7KD 30.06.2019 01:08
Прошу помощи. У меня при парсинге с другова сайта идет следующий код
Код:<iframe width="100%" height="350" src="https://www.youtube.com/embed/BnR1MfWbKhM" frameborder="0" allowfullscreen=""></iframe>
Мне надо вырезать из этого кода Код:width="100%" height="350" к записи на сайт.
Можно ли вырезать Код:width="100%" height="350"
Если это возможно, напишите код скрипт с помощью которого я это могу сделать.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Настя999
0 # Настя999 30.06.2019 01:19
Прошу помощи. У меня при парсинге с другова сайта идет следующий код
Код:<iframe width="100%" height="350" src="https://www.youtube.com/embed/BnR1MfWbKhM" frameborder="0" allowfullscreen=""></iframe>
Мне надо вырезать из этого кода Код:width="100%" height="350" к записи на сайт.
Можно ли вырезать Код:width="100%" height="350"
Если это возможно, напишите код скрипт с помощью которого я это могу сделать.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
browser games
0 # browser games 25.05.2020 02:18
Hi there colleagues, its enormous paragraph regarding teachingand completely explained, keep it up all the time.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Royal CBD
0 # Royal CBD 25.05.2020 15:42
Hello there! This is kind of off topic but I need some advice from an established blog.
Is it tough to set up your own blog? I'm not very techincal but I can figure things out pretty fast.
I'm thinking about making my own but I'm not sure where to start.
Do you have any points or suggestions? Appreciate it

P.S. If you have a minute, would love your feedback on my new website
re-design. You can find it by searching for «royal cbd» — no sweat if you can’t.



Keep up the good work!
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
browser games
0 # browser games 25.05.2020 19:38
constantly i used to read smaller content that also clear their motive, and
that is also happening with this paragraph which I am reading
at this time.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору