2014-11-16 2 views
1

Мне нужно напечатать конкретную div с классом productSpecs с веб-страницы. Вот мой код.Perl - Печать div по классам

use strict; 
use LWP::Simple; 
use HTML::TreeBuilder::XPath qw(); 

my $url="http://www.flipkart.com/samsung-b310e-guru-music-2/p/itmdz9am8xehucbx"; 
my $content = get($url); 
my $t = HTML::TreeBuilder::XPath->new; 
$t->parse($content); 
my $rank = $t->findvalue('//*[@class="productSpecs"]'); 
print $rank; 

Но я не получаю контент, который я хочу. Что не так с моим кодом?

ответ

3

Проверка HTML код, который вы пытаетесь разобрать, необходимый div узел имеет это заявление:

<div class="productSpecs specSection"> 

так что ваш код должен быть:

my $rank = $t->findnodes('//div[@class="productSpecs specSection"]'); 
+0

Я дает текст ... но мне нужно это с HTML ... Как я могу получить HTML внутри элемента сНа? – user2186465

+0

+1 хороший ловушка :-) Я продолжил свой ответ в своем и попытался объяснить, почему появился только рендер, но не полный HTML. –

1

Привет user2186465 Добро пожаловать в Stack обмен: -)

Когда вы назначаете и печатаете вывод из HTML::TreeBuilder::XPath метода findnodes->(), по умолчанию он по-разному обрабатывает/выполняет рендеринг узел <div> и возвращает содержимое в виде текста. Наряду с этим он возвращает объект XML::XPathEngine::NodeSet (который использует HTML::TreeBuilder::XPath) и массив со ссылкой на объект HTML::Tree, который имеет то, что вы хотите. Вы должны назначить этот опорный элемент массива к вашим $rank переменным, иначе вы просто получите текст:

my $rank = $t->findnodes('//div[@class="productSpecs specSection"]')->[0]; 

(NB: это появляется где-то в документации в качестве примера, но не выдающийся) , Как только у вас есть объект HTML::Element, вы можете использовать один из его методов с помощью инструкции печати, чтобы получить содержимое.

Без ->[0] вы получаете визуализированный текст, а print $rank просто показывает, что; но с ->[0] вы получаете доступ к объекту и его методам, поэтому print $rank->as_HTML может отображать необработанный HTML-контент с узла (->as_XML также работает). HTML::TreeBuilder::XPath также имеет удобный способ as_XML_indented, чтобы облегчить чтение. Таким образом:

use strict;                
use LWP::Simple;                
use HTML::TreeBuilder::XPath qw();         

my $url="http://www.flipkart.com/samsung-b310e-guru-music-2/p/itmdz9am8xehucbx"; 
my $content = get($url);               
my $t = HTML::TreeBuilder::XPath->new; 
$t->parse($content); 
my $rank = $t->findnodes('//div[@class="productSpecs specSection"]')->[0]; 
print $rank->as_XML_indented ; 

должно делать то, что вы хотите.

НТН

1

Для сравнения я попытался это с помощью Mojolicious ojo инструмента (отлично подходит для oneliners) и, кажется, Mojo::DOM возвращает HTML по умолчанию, если вы не попросите текста с методом ->text(). , например. это, кажется, что вы хотите:

perl -Mojo -E 'g("http://www.flipkart.com/samsung-b310e-guru-music-2/p/itmdz9am8xehucbx") 
->dom->find("div.productSpecs")->each(sub{say $_})' 

приветствий,

Смежные вопросы