Can't locate module(s) using Mojo::DOM

871 views Asked by At

I'm new to Mojolicious. I am sure this is probably a setup problem, but it's eaten up an entire day of my time. I'm trying to run this simple test code

#!/usr/bin/perl

use strict;
use warnings;
use Mojo::DOM;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new();

$ua->get('https://stackoverflow.com/questions/26353298/find-links-containing-bold-text-using-wwwmechanize')->res->dom('a div')->ancestors('div.spacer')->each( sub { say $_->all_text } );

which I found at this location

find links containing bold text using WWW::Mechanize

and it is failing with

Can't locate object method "ancestors" via package "Mojo::Collection" at ./test4.pl line 10.

I've deinstalled and reinstalled a jillion times, tried different package installation options (cpan, cpanm, direct link, etc). No dice. I am mildly confused that the Mojo::Collection module does not appear to have an "ancestors" method in it (inherited or no), but I've seen several other examples like this which appear to use the same method in the same way. It's not just the "ancestors" module, either -- the problem seems to be affecting a few other methods as well.

I'm using perl 5.18.2 on Linux Mint with Mojolicious package 6.11.

Thanks for any help.

1

There are 1 answers

2
Borodin On BEST ANSWER

It's very difficult to debug a single long chained statement like that, and you're much better off splitting it into individual steps

Passing a parameter to the dom method is the same as calling find with that parameter on the DOM object. find returns a Mojo::Collection, which makes sense as it's the set of nodes that match the CSS selector. The ancestors method applies only to a single node, so you have to pick one out with something like first or last, or process them all one at a time using each

Here's a rewrite of your code that produces what I assume is the expected result

use strict;
use warnings;
use 5.010;

use open qw/ :std :encoding(UTF-8) /;

use Mojo;

my $url = 'http://stackoverflow.com/q/26353298';

my $ua = Mojo::UserAgent->new->max_redirects(3);
my $dom = $ua->get($url)->res->dom;

my $divs = $dom->find('a div');

printf "%d matching div elements:\n\n", $divs->size;

my $n;
for my $div ( $divs->each ) {
  my $spacers = $div->ancestors('div.spacer');
  for my $spacer ( $spacers->each ) {
    printf "%2d -- %s\n\n", ++$n, $spacer->all_text;
  }
}

output

20 matching div elements:

 1 -- Stack Exchange Podcast #65: The Word Has Two Meanings, You See

 2 -- PIVOTing into a new career: please welcome Taryn Pratt, bluefooted Community …

 3 -- 0 Can't locate module(s) using Mojo::DOM

 4 -- 0 tiny runable www::Mechanize examples for the beginner

 5 -- 2 Perl WWW::Mechanize and authenticated proxy

 6 -- 0 How to process a simple loop in Perl's WWW::Mechanize?

 7 -- 1 not able to click a button in www::mechanize perl

 8 -- 0 Perl - Mechanize? - How to get all links in a page up to a specific “delimiter” text

 9 -- 2 Why am I getting gibberish content using Perl's WWW::Mechanize?

10 -- 1 Getting error in accessing a link using WWW::Mechanize

11 -- 3 Perl WWW::Mechanize Web Spider. How to find all links

12 -- 0 What is the best way to extract unique URLs and related link text via perl mechanize?

13 -- 0 perl WWW::Mechanize file upload error