24

I need to parse some markup similar to this one, from an html page:

<div id="list">

  <div class="item-level-a">
    <div class="item-level-b">
      <a href="http://www.example.com/1"></a>
    </div>
  </div>

  <div class="item-level-a">
    <div class="item-level-b">
      <a href="http://www.example.com/2"></a>
    </div>
  </div>

  <div class="item-level-a">
    <div class="item-level-b">
      <a href="http://www.example.com/3"></a>
    </div>
  </div>

</div>

I did try with this code:

$list = [];
$('div[id="list"]').each(function() {
  var href = $(this).find('div > div > a').attribs('href');
  list.push(href);
});

without success: error was:

TypeError: Object <a href="http://www.example.com/1"></a>
                  <a href="http://www.example.com/2"></a>
                  <a href="http://www.example.com/3"></a>
has no method 'attribs'

:-(.

Any clue?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
MarcoS
  • 17,323
  • 24
  • 96
  • 174

3 Answers3

46

In cheerio and jquery, you get attributes with attr(), not attrib().

There are a few other problems with your code. Here is a working version using cheerio. It probably works in jquery this way as well.:

var list = [];
$('div[id="list"]').find('div > div > a').each(function (index, element) {
  list.push($(element).attr('href'));
});
console.dir(list);
Trott
  • 66,479
  • 23
  • 173
  • 212
  • 5
    Great! Thanks, it works like a charm (I'm feeling quite dumb right now... :-() – MarcoS Sep 18 '15 at 15:20
  • 9
    Feel good about your question! It provides all the relevant information one would want to solve your problem without overwhelming with a lot of irrelevant stuff. – Trott Sep 18 '15 at 15:49
  • 1
    Thank you @Trott, I have been trying to target html elements for a while and your example help me a lot :) – Kristiyan D Kovachev Apr 23 '18 at 10:38
17

For those who prefer a functional style:

const list = $('div[id="list"]')
  .find('div > div > a')
  .toArray()
  .map(element => $(element).attr('href')));
sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
1

Spread syntax also works for getting out of jQuery-style iteration functions:

const hrefs = [...$("div#list div > div > a")].map(e => $(e).attr("href"));

There's no need for the extra .find() call since querying ancestors deeply is supported in a single CSS selector.

ggorlen
  • 44,755
  • 7
  • 76
  • 106