LoginSignup
6
6

More than 3 years have passed since last update.

PHPでWebスクレイピング(PHPネイティブでなるべく簡単に)

Last updated at Posted at 2020-08-22

長めの前書き。

Webスクレイピング、藤井聡太です。(あいさつ)

「将棋なんか指したことあんの(´・_・`)」

もちろん、ニセモノです。私は藤井八段などではなく無冠の一介のサラリーマンプログラマーです。なので、将棋の天才となってウハウハ、なんて夢はあきらめて地道に稼ごうと思います「当たり前だ(´・_・`)」

稼ぐ、といえば。とあるプログラミング動画を見ておりましたらば、最近の稼げるプログラミング技術ベストスリーは1.WebAPI、2.Webスクレイピング、3.LINEチャットボット、なんだそうです。うち、LINEは好きじゃないので却下、WebAPIは今、実際の業務でやっておりますので残る「Webスクレイピング」につきまして今回、PHPでチャレンジしてみようと思います。稼げるプログラマーになって、コレで老後もウハウハです。

PHPQuery以外の選択肢を検討

ところで、PHPでWebスクレイピング!といってググってみるとめちゃくちゃ「PHPQuery」ってヤツばっかり出てくるんですが…(´・_・`)

しかし、アレでしょ?10年くらいアプデされてない、だっさいライブラリなんでしょ?却下だ却下。

んで代わりに押されたのが「Simple HTML DOM Parser」でこちらは使い方はPHPQueryライクで使いやすいんだとか。しかし↓のページ

PHPネイティブのDOMによるスクレイピング入門 - Qiita

によると内部で何回も正規表現を使って全ての要素をパースしてるので遅いんだそうです。他のライブラリとしては「Goutte」というのもあり、こちらは内部でPHPネイティブのDOMを使っているそうなんでよさそうですが、しかし、せっかくだから(座右の銘)、先のページで提示されていた、「ライブラリ追加せずにPHPネイティブのDOMでやる」というのを試してみることにしました。

カンタンなやつからいきます

なるべく単純でカンタンなことからやってみよう、と思いまして。そんでタイトルだけ取るとかなら、要素1コだけだから楽勝でしょ

…と思ったら「文字化け」というワナにハマりました(´・_・`)なんとか文字化けを克服したのが下のコードです。

<html>
<?php
  $dom = new DOMDocument('1.0', 'UTF-8');
  $html = file_get_contents("https://b.hatena.ne.jp/hobonichi1101/");
  $html = mb_convert_encoding($html, "HTML-ENTITIES", 'auto');
  @$dom->loadHTML($html);
  $xpath = new DOMXpath($dom);
  $title = $xpath->query("//title")->item(0)->nodeValue;
  echo $title;
?>
</html>

サンプルをはてブにしたの失敗だったかなあ。HTMLにクセがあるんだよなあ。

複数要素をとりこむ

上のコードを改良して、対象のはてブのリンク部分を取得します。

<html>
<?php
  $dom = new DOMDocument('1.0', 'UTF-8');
  $html = file_get_contents("https://b.hatena.ne.jp/hobonichi1101/");
  $html = mb_convert_encoding($html, "HTML-ENTITIES", 'auto');
  @$dom->loadHTML($html);
  $xpath = new DOMXpath($dom);
  foreach ($xpath->query("//li[@class='bookmark-item js-user-bookmark-item']") as $node) {
    echo '<p>';
    echo '<a href="';
    echo $xpath->evaluate('string(.//@href)', $node);
    echo '">';
    echo $xpath->evaluate('string(.//a)', $node);
    echo '</a>';
    echo '</p>';
  }
?>
</html>

軽く説明しますと、はてなブックマークのリンク部分はリスト形式になっていまして、bookmark-item js-user-bookmark-itemというclass属性をもっております。なので$xpath->queryに

//li[@class='bookmark-item js-user-bookmark-item']

と指定してやるとその全てを取得できます。んで、取得した要素をforeachでループ回しながら、その中に含まれているA属性のテキストとhref属性(リンクurl)をそれぞれ

$xpath->evaluate('string(.//a)', $node);
$xpath->evaluate('string(.//@href)', $node);

で取得します。以上。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6