ウェブから情報をあつめる
DESCRIPTION
NAVER まとめを題材に、ウェブから情報を集めるクローラ、スクレイパーの設計についてTRANSCRIPT
ウェブから情報をあつめる
04/13/2023 UT Startup Gym1
UT Startup Gym
UT Startup Gym とは?
アイデアをカタチにするプログラム
04/13/2023 2
プロジェクト企画から実装までスタートアップ
UT Startup Gym
スケジュール
04/13/2023 3
Oct, 12
• プログラミング入門
Nov,
12
• プラニング• プロジェクトスタート
Dec,
12
• 開発開始• 冬季開発合宿
Jan, 13
• ウェブデザイン• 週間報告会
Feb, 13
• jQuery, 中間発表
Mar,
13
• 作業会
Apr, 13
• リリース会
ソーシャルウェブアプリケーション , API,bot, HTML5
Keywords:
リーンスタートアップ , ビジネスプラニング , HTML, CSS, PHP, javascript
チーム結成 , 企画 , ディスカッションgit, フレームワーク , MySQL, Apache
シナリオ , ペルソナ , ワイヤフレーム , サイトマップ , DB スキーム
ゲーミフィケーション , 仮説検証 , データマイニング , アクセシビリティ
レスポンシブデザイン , プレゼンテーション
UT Startup Gym
M D 講師(敬称略) タイトル 要素
10 13飯塚 かんたん Facebook アプリをつくる HTML, CSS, js
21飯塚 かんたん Twitter アプリをつくる UNIX, vim, PHP
27 川上 かんたん アンケートフォームをつくる MySQL, MVC
11 4AWS 高山様 サーバを立てよう AWS
10飯塚・石村 スタートアップの心構え ビジネスプラン、リーンスタートアップ
17飯塚・佐藤 プロダクトデザイン シナリオ、ペルソナ、ワイヤフレーム
24 お休み(飯塚 @ ジャカルタ)
12 1ゆーすけべー様 ウェブサービスの企画のコツ 企画プロセス、ウェブサービス運用
8飯塚 ウェブから情報をあつめる クローラ , XPath, 正規表現
15 プロジェクトキックオフ アンカンファレンス
22 ハッカソン
1 12石村 ユーザがハマるアプリデザイン ゲーミフィケーション 19飯塚 かんたん・きれい・便利なウェブデザイン Twitter Bootstrap, Responsive Design, LESS
26未定 Git
2 2斎藤 アニメーションをつくる javascript, jQuery
9ゲスト ゲストスピーカー
16 中間発表
3 作業会
4 13 プレゼンテーション
20 リリース会
04/13/2023 4
UT Startup Gym
目次• イントロダクション• ソースコードを取ってくる
– PHP file_get_contents($url)
• HTML を解析する– 正規表現– XPath
• 自動的で動かす– cron
04/13/2023 5
UT Startup Gym
クローラってなに?
• 自動的にウェブページにアクセスし、データを収集するプログラム。ロボットとも言う。
• これを走らせることを「クローリング」という。
• スクレイピング= HTML を解析して、必要な情報を抜き出すこと。
04/13/2023 6
UT Startup Gym
クローラとウェブアプリ
• いきなり充実したコンテンツのサイトができる
• 広告をつければ「サーバに稼いでもらう感覚」を手っ取り早く味わうことができる
04/13/2023 7
UT Startup Gym
Spysee
04/13/2023 8
UT Startup Gym
Bijostagram
04/13/2023 9
UT Startup Gym
ソースコードを取ってくる• とりあえず名言ページを題材に
file_get_contents() の使い方に慣れる
04/13/2023 10
UT Startup Gym
ソースコードを取ってくる1<?$url = "http://www.meigensyu.com/quotations/view/random";$html = file_get_contents($url);echo $html;
04/13/2023 11
UT Startup Gym
ソースコードを取ってくる2<?$url = "http://www.meigensyu.com/quotations/view/random/";$html = file_get_contents($url);preg_match('/<div class="text">(.+)<\/div’>/', $html, $match);var_dump($match);
04/13/2023 12
UT Startup Gym
正規表現
• 任意の文字列に対して、指定したパターンにマッチしているかを試す
• パーサーではないので、構造を持ったデータには弱い
• 構造を持たないフラットなデータに良い。– トークナイザ– バリデータ
04/13/2023 13
UT Startup Gym
正規表現の例• ^\d+$ → 1234 とか 39843452 にマッチ。
12 324 とか ff0000 とかにはマッチしない。– ^: 行頭– \d: 半角数字– +: 1回以上の繰り返し– $: 行末
• ^[A-Z]*(\d+)$ → 13 とか ADB1132 にマッチ。しかも、 13 とか 1132 が抜き出せる。– *: 0回以上の繰り返し– (): 抜き出す
04/13/2023 14
UT Startup Gym
HTML を解析する1• NAVER まとめの記事ページから、写真の URL
だけを収集する• とりあえず単一ページで動作
04/13/2023 15
UT Startup Gym
HTML を解析する1<?$url = "http://matome.naver.jp/odai/2133765614325689001";$res = file_get_contents($url);$dom = @DOMDocument::loadHTML($res);$xml = simplexml_import_dom($dom);$imgs = $xml->xpath("//img[@class='MTMItemThumb']");foreach ($imgs as $img) { echo $img["src"]."\n"; //echo "<img src='".$img["src"]."'>\n";}
04/13/2023 16
UT Startup Gym
XPath
• XML や HTML の任意の位置を取得するための式– プログラミング言語に依らない
• XPath エンジンがあれば、 XPath を指定して HTML 上の値を簡単に持って来ることができる
04/13/2023 17
UT Startup Gym
XPath の例
• //img[@class=‘MTMItemThumb’]→class 属性の値が‘ MTMItemThumb’ の img 要素– // は /html/body の短縮形– @ は属性のこと (@id=, @src=, @href= etc.)
• 他にも、様々な表現方法がある
04/13/2023 18
UT Startup Gym
ブラウザで表示する
$ php hoge.php > piyo.html
04/13/2023 19
生成された HTML ファイルをブラウザで表示してみよう。
//echo $img[“src”].“\n”;echo “<img src=‘”.$img[“src”].“’>\n”;
UT Startup Gym
HTML を解析する2• 食べログの検索結果から店名と URL 、食べログ
得点を取得する。
04/13/2023 20
UT Startup Gym
HTML を解析する2<?$url = 食べログ検索結果の URL;$res = file_get_contents($url);$dom = @DOMDocument::loadHTML($res);$xml = simplexml_import_dom($dom);$shops = $xml->xpath("//li[contains(@class,'rank')]");foreach ($shops as $shop) { $name = $shop->div[0]->div[0]->div[0]->strong[0]->a; echo "Shop Name: $name\n"; echo "URL: ".$name["href"]."\n"; $rank = $shop->div[2]->div[0]->p[0]->em; echo "Rank: $rank\n\n";}
04/13/2023 21
UT Startup Gym
HTML を解析する3• アルク 英辞郎• 英単語の難度、発音を知りたい• 普通にやると、詰まる
– User Agent で制限をかけている
※このコードが実行できない場合、 PHP むけ cURL をインストールすること。$ sudo apt-get install php5-curl
04/13/2023 22
UT Startup Gym
HTML を解析する3(できない)<?if (isset($argv[1])) { $query = $argv[1]; $res = file_get_contents("http://eow.alc.co.jp/$query/UTF-8/"); // ブラウザでは見られるのに、ソースコードを取得できない $dom = @DOMDocument::loadHTML($res); $xml = simplexml_import_dom($dom); $properties = $xml->xpath('//span[@class="label" and .= "【@】 " ]/following-sibling::text()[1]'); if (!empty($properties)) { $prop_array = explode(" 、 ", $properties[0]); echo "[".$query."] レベル : ".$prop_array[0]." ヨミ : ".$prop_array[1]."\n"; } else { echo " 結果を取得できませんでした。正しい英単語を入力してください。 \n"; }}
04/13/2023 23
UT Startup Gym
HTML を解析する3(できる)<?if (isset($argv[1])) { $query = $argv[1]; $doc = new DOMDocument(); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://eow.alc.co.jp/$query/UTF-8/"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //標準出力でなく、文字列として取得 curl_setopt($ch, CURLOPT_USERAGENT, “Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1” ); //Firefox のふりをしてアクセス $res = curl_exec($ch); curl_close($ch); $dom = @DOMDocument::loadHTML($res); $xml = simplexml_import_dom($dom); $properties = $xml->xpath('//span[@class="label" and .= "【@】 " ]/following-sibling::text()[1]'); if (!empty($properties)) { $prop_array = explode(" 、 ", $properties[0]); echo "[".$query."] レベル : ".$prop_array[0]." ヨミ : ".$prop_array[1]."\n"; } else { echo " 結果を取得できませんでした。正しい英単語を入力してください。 \n"; }} else { echo " 検索する英単語を入力してください。 \n";}
04/13/2023 24
UT Startup Gym
HTML を解析する4• NAVER まとめふたたび• このままだと、1ページ目しか収集できない• 自動で次ページの収集もできないか?
04/13/2023 25
UT Startup Gym
HTML を解析する4if (isset($argv[1])) { if (preg_match("/http:\/\/matome\.naver\.jp\/odai\/(\d+)$/", $argv[1])) { $url = $argv[1]; $res = @file_get_contents($url); while ($res) { $data = getData($res); foreach ($data["image"] as $image) { echo "<img src='".$image["src"]."'>\n"; } if (!$data["nextPage"]) { $res = null; } else { $res = @file_get_contents($url."?page=".$data["nextPage"]); } sleep(1); } }}つづく ...
04/13/2023 26
UT Startup Gym
HTML を解析する4function getData ($html) { $dom = @DOMDocument::loadHTML($html); $xml = simplexml_import_dom($dom); $result["image"] = $xml->xpath("//img[@class='MTMItemThumb']"); $pager = $xml->xpath("//div[@class='MdPagination03']"); $result["nextPage"] = null; if (!empty($pager)) { $last_anchor = $pager[0]->a[count($pager[0]->a)-1]; $current_page = $pager[0]->strong; if ($last_anchor + 1 != $current_page) { $result["nextPage"] = $current_page + 1; } } return $result;}
04/13/2023 27
UT Startup Gym
cron
• 定期的にプログラムを実行• とても簡単• コマンドラインで動くプログラムをその
まま使える
04/13/2023 28
UT Startup Gym
cron
04/13/2023 29
$ vim crontab.txt
# フルパスで記述すること# 毎日 4 時 12 分に実行12 4 * * * php /home/user/crawl_user_page.php
# 毎分実行* * * * * php /home/user/crawl_top_page.php >>/home/user/log.txt
$ crontab < crontab.txt # ジョブの登録$ crontab –l
# 登録されたジョブの確認$ crontab –e
# ジョブの編集$ crontab –r
# ジョブの全消去
UT Startup Gym
自動でプログラムを動かす<?$article = getRSS();$res = @file_get_contents($article->link);while ($res) { $data = getData($res); foreach ($data["image"] as $image) { echo "<img src='".$image["src"]."'>\n"; } if (!$data["nextPage"]) { $res = null; } else { $res = @file_get_contents($url."?page=".$data["nextPage"]); } sleep(1);} つづく ...
04/13/2023 30
UT Startup Gym
自動でプログラムを動かすfunction getData ($html) { $dom = @DOMDocument::loadHTML($html); $xml = simplexml_import_dom($dom); $result["image"] = $xml->xpath("//img[@class='MTMItemThumb']"); $pager = $xml->xpath("//div[@class='MdPagination03']"); $result["nextPage"] = null; if (!empty($pager)) { $last_anchor = $pager[0]->a[count($pager[0]->a)-1]; $current_page = $pager[0]->strong; if ($last_anchor + 1 != $current_page) { $result["nextPage"] = $current_page + 1; } } return $result;} つづく ...
04/13/2023 31
UT Startup Gym
自動でプログラムを動かすfunction getRSS() { $xml = simplexml_load_file("http://matome.naver.jp/feed/topic/1Luvh"); $items = array(); foreach ($xml->channel->item as $item) { $items[] = $item; } shuffle($items); return $items[0];}
04/13/2023 32
UT Startup Gym
ワーク
• 何かできそうな気がして来ませんか?• 自分が面白そうと思うサイトから情報を集めて
くる。• 複数サイトからの情報を組み合わせていると
GOOD 。(マッシュアップ)
04/13/2023 33