1

Hi I'm running into a little problem with DomCrawler. I'm scraping a page and it has a div with a class of .icon3d. I want to go through the page and for every div with that class I will add an "3D" item to an array, and every div without it I will add a "2D" item. Here is the code I have so far.

for ($i=0; $i < 10; $i++) { 
    $divs =  $crawler->filter('div.icon3d');
        if(count($divs)){
            $type[] = '3D';
        }else{
            $type[] = '2D';
        }
    }
icetimux
  • 215
  • 1
  • 4
  • 11
  • What's the problem you're running into? – aholmes Jul 09 '15 at 02:40
  • currently when I return the `$type` array it returns full of `"3D"` while in reality there only about 4 of them on that page. (only about 4 divs with the .icon3d class). what I want is an array that has the `"3D"` and `"2D"` values in them in the same order as they appear on the page. – icetimux Jul 09 '15 at 03:30
  • Have you tried with if($crawler->filter('.icon3d')->count()) {} else {} – Sachin I Jul 09 '15 at 08:13
  • @sAcH yea, no success. that always avaluates to true because `$crawler->filter('.icon3d')` is 4 – icetimux Jul 09 '15 at 11:14

2 Answers2

4

Check The DomCrawler Component documentation first. filter method returns filtered list of nodes, so by calling ->filter('div.icon3d') returned value will be list of all div elements which have icon3d class.

First you need to find all div elements, loop through them and add either 3D or 2D the to array depending on icon3d css class existance.

$divs = $crawler->filter('div');
foreach ($divs as $node) {
    $type[] = (false !== strpos($node->getAttribute('class'), 'icon3d')) ? '3D' : '2D';
}

UPDATE

$crawler->filter('a')->each(function(Crawler $a) {
    $div = $a->filter('div');
    // Div exists
    if ($div->count()) {

    }
});

To get crawler node class use

$div->getNode(0)->getAttribute('class')
Vadim Ashikhman
  • 9,851
  • 1
  • 35
  • 39
0

I figured it out. Here's the code I used. I'm sure there is a cleaner way.

$divs = $crawler->filter('#schedule li a')->each(function($node){
    if ($node->children()->last()->attr('class') == 'icon3d') {
        return '3D';
    }else{
        return '2D';
    }
});
icetimux
  • 215
  • 1
  • 4
  • 11
  • This only matches, if the node has the correct matching class. If you element has more than one class, this will not work! – Roman Jul 22 '18 at 10:02
  • you can improve this answer by doing this instead `$classes = preg_split('/\s+/', ($innerNode->attr('class') ?? "")); in_array("searching_class", $classes);` – user151496 Jul 09 '23 at 19:42