2012-07-31 13 views
5

Piszę podstawowy skrypt, który po prostu wyciąga wszystkie linki ze strony internetowej. Został napisany w Perlu i korzysta z modułów WWW :: Mechanize i HTML :: Treebuilder :: Xpath, które zostały zainstalowane przez CPAN.HTML Treebuilder XPath do ekstraktów

Wiem, że można to łatwo zrobić za pomocą tylko WWW :: Mechanize, jednak chciałbym nauczyć się tego również przy użyciu XPath.

Tak więc skrypt przeanalizuje całą stronę internetową i sprawdzi atrybut href dla każdego znacznika zakotwiczenia, wyodrębni łącze i wydrukuje je na konsoli/zapisze w pliku. Zauważ, że w poniższym scenariuszu nie użyłem ścisłego użycia, ponieważ piszę to tylko w celu wyjaśnienia i zrozumienia pojęcia używania XPath do przechodzenia przez drzewo HTML.

oto skrypt:

#! /usr/bin/perl 

use WWW::Mechanize; 
use HTML::TreeBuilder::XPath; 
use warnings; 

$url="https://example.com"; 

$mech=WWW::Mechanize->new(); 
$mech->get($url); 

$tree=HTML::TreeBuilder::XPath->new(); 

$tree->parse($mech->content); 

$nodes=$tree->findnodes(q{'//a'}); # line is modified later. 

foreach $node($nodes) 
{ 
    print $node->attr('href'); 
} 

I to daje błąd:

Can't locate object method "attr" via package "XML::XPathEngine::Literal" at pagegetter.pl line 23. 

zmodyfikowałem skrypt w następujący sposób:

$nodes=$tree->findnodes(q{'//a/@href'}); 

while($node=$nodes->shift) 
{ 
    print $node->attr('href'); 
} 

Błąd:

Can't locate object method "shift" via package "XML::XPathEngine::Literal" 

Nie jestem pewien, jak wydrukować wartość atrybutu href.

$ węzły powinny zawierać listę wszystkich atrybutów href? Uważam, że nie przechowuje wartości, ale zamiast tego wskazuje na nią?

Próbowałem wyszukiwać i czytać przykłady, ale nie jestem pewien, jak się do tego zabrać.

Dzięki.

+0

Powinieneś zawsze używać 'strict ', bez względu na trywialny program. Jest prawdopodobnie ważniejsze, że użyjesz ostrzeżeń, które wybrałeś. – Borodin

Odpowiedz

4

Jest kilka błędów. Naprawy:

# list context 
my @nodes = $tree->findnodes(
    q{//a}  # just a string, not a string containings quotes 
); 

# iterate over array 
for my $node (@nodes) { 
+0

Powinieneś użyć XPath z '// a [@href]', aby znaleźć wszystkie elementy zakotwiczenia z atrybutem 'href' – Borodin

+0

Dzięki. Uzgodnione, ale co dokładnie drukujesz w For Loop? I tak, chcę wyodrębnić linki? –

+0

@NeonFlash: Reszta kodu pozostaje taka, jaka jest. Po prostu 'print $ node-> attr ('href')," \ n "' – Borodin

Powiązane problemy