How to use CHEERIO.js for this HTML?

cheerio, javascript, node.js, web-scraping

Solution

You want to use a better selector string to target the element & attribute of interest. Exactly how vague or precise you go involves trade-offs of coupling too tighly to the DOM structure and thus some irrelevant change to the HTML means your selector doesn't match anymore or using too vague a selector and matching more stuff than you intend.

- vaguest: `'a'` (find every anchor)

- `'.A a'` (every anchor inside the div class="A")

- Recommended: `'.A li a'` (must be part of a list)

- crazy specific: `'div.A section.B ul.list li a'`

.

var link = $('.A li a');
var href = link.attr('href');
var spanText = link.find('span').first().text();

Problem

``` <div class="A"> <section class="B" data-vr-zone="B"> <header class="C"> BarFoo</header> <ul class="list"> <li data-vr-contentbox=""> <a href="http://www.foobar.com/.../html"> <small>BarBar</small> <span>Foo Bar foobarbar FooFoo?</span> </a> </li> <li data-vr-contentbox=""> <a href="http://www.foofoobar.com/.../html"> <small>BarBarBar</small> <span>Foo foo FooFoo?</span> </a> </li> ``` I want to access the url in the HREF attribute. And the text in the SPAN -- Of only the first list item. What I have works but I'm looking to learn a better way. `var url = $('div .A').children().children().children().children()[0].attribs.href;` `var title = $('div .A').children().children().children().children()[0].children[2].children[0].data;`

Original source