k47.cz    — každý den dokud se vám to nezačne líbit
foto Praha výběr povídky kultura | twitter FB


Atrox\Matcher

23. 3. 2012 — k47 (CC by-sa)

Tak dlouho jsem se hrabal v cizím HTML kódu, scrapoval, crawloval, parsoval, až jsem si napsal Atrox\Matcher, který tuhle práci velice usnadňuje.


Matcher provádí stromové xpath dotazy, které transformují DOM dokument na PHP pole.

Například Matcher může vypadat následovně:

$matcher = Matcher::mutli('//div[@class="article"]', array(
  'title' => './h2',        // plný xpath výraz: //div[@class="article"]/h2
  'text'  => './text()',
  './div[@class="info"]' => array(
    'date'   => './div[@class="date"]', // plný xpath výraz: //div[@class="article"]/div[@class="info"]/div[@class="date"]
    'author' => './div[@class="author"]',
  ),
  'tags' => Matcher::multi('.//a[@class="tag"]'),
  'comments' => Matcher::multi('./div[@class="comment"]', array(
    'author' => './div[@class="author"]',
    'text'   => './div[@class="comment-text"]',
  )),
));

Pracuje se s ním jako s obyčejnou funkcí, která jako argument čeká objekt DomDocument (takže se hodí nejen pro scrapování HTML, ale i pro práci s různými API, které vracejí XML).

$matcher($dom);

// nebo

$matcher->processHtml($htmlData);

Výsledná data budou v tomto formátu:

array(
  array(
    'title' => 'xxx',
    'text' => 'txt',
    'date' => '2011-01-01',
    'author' => 'anon',
    'tags' => array('tag1', 'tag2'), // Matcher::multi s jedním argumentem
    'comments' => array( // Matcher::multi se dvěma argumenty
      array(
        'author' => 'anon',
        'text' => 'txt',
      ), // + další komentáře
    )
  ), // + další články
);

Pěkné, co?


Aktualizace:

Matcher má dvě možnosti jak z DOMNode získat nějaké smysluplné hodnoty.

Globálně se zadává jako třetí parametr metody multi:

Matcher::multi('//article', array(
  'title' => 'div[@class="title"]',
  'text'  => 'div[@class="text"]',
), function ($n) { return trim($n->nodeValue); }); // když nic nezadáte, zavolá se `$node->nodeValue`.

Nebo lokálně pro každou položku zvlášť:

Matcher::multi('//article', array(
  'title' => 'div[@class="title"]',
  'date' => Matcher::single('div[@class="date"]', function ($n) { return strtotime($n->nodeValue); }),
));
vstoupit do diskuze    sdílet na facebooku, twitteru, google+

štítky: #programování «« »» #obsah «« »» #programování #PHP

publikováno 23. 3. 2012

příbuzné články:
PHP 5.4
Spellcheck
Operace Tripkodér
get_calling_class() pro PHP 5.2 📷
Scala - konverze TupleN na case class 📷
Scala - Booleovská kompozice funkcí 📷

sem odkazují:
XPath.scala 📷
Prog smetí

píše k47 & hosté, ascii@k47.cz