スクレイピングをする必要があり色々と試したので軽くメモを残す。
以前、試した事があるのでそれをベースに実行をした。同じくSimple HTML DOM Parserを使っている。
対象のページは上場企業の情報が掲載されているUllet(ユーレット)でここから上場企業リストと従業員数等の情報を取り出したい。
1ページあたり20社ずつ企業一覧になっており193ページあるようで、下記のURLが1ページ目になる。
http://www.ullet.com/searchd/page/1.html
そこから2.html,3.htmlと続き193.htmlまでと連番になっている。
それぞれの企業のリンクをたどり詳細ページに進むと従業員数の記載があるのだが、まずはその詳細ページのURLを全件取得したい。
まずは詳細ページURLのリンクの取得から。
http://www.ullet.com/searchd/page/1.html のHTMLを確認すると、一番目の「トヨタ自動車」はaタグにcompany_name0のidがついている事が確認できた。
<td align="left"> <a href="/7203.html" id="company_name0" class="company_name" onmouseover="onmouseover_object_name( event, 'company_name0', {'company':{'no':7203,'name':'トヨタ自動車','group_no':17,'group_name':'輸送用機器','market_no':1,'market_name':'東証1部','star':5},'stock':{'no':90297,'name':'トヨタ自動車','amount':'5.2兆円','num':'59'}} )"><img src="/img/icon/company_stock.gif?209" alt="企業兼大株主" height="13" width="20" />トヨタ自動車</a> </td>
トヨタ自動車の詳細ページのURLは http://www.ullet.com/7203.html なので、そこを取り出してみる。
<?php include_once('simplehtmldom_1_5/simple_html_dom.php'); $url = 'http://www.ullet.com/searchd/page/1.html'; $contents = file_get_contents($url); $content = mb_convert_encoding($contents, 'UTF-8', 'auto'); $html = str_get_html($content); $result = $html->find("a[id=company_name0]"); foreach($result as $element){ echo "http://www.ullet.com" . $element->href; }
上記のコードを実行すると http://www.ullet.com/7203.html が表示される。
続いて、2番目の「本田技研工業」を取得するには単純にa[id=company_name0]をa[id=company_name1]にすれば良いのであるが、複数取得したい場合はカンマ区切りにする。a[id=company_name0],a[id=company_name1]みたいな感じで。
<?php include_once('simplehtmldom_1_5/simple_html_dom.php'); $url = 'http://www.ullet.com/searchd/page/1.html'; $contents = file_get_contents($url); $content = mb_convert_encoding($contents, 'UTF-8', 'auto'); $html = str_get_html($content); $result = $html->find("a[id=company_name0],a[id=company_name1]"); foreach($result as $element){ echo "http://www.ullet.com" . $element->href . PHP_EOL; }
改行をしたいのでPHP_EOLを入れた。
上記のコードを実行すると下記の結果が取得できる。
http://www.ullet.com/7203.html http://www.ullet.com/7267.html
http://www.ullet.com/searchd/page/1.html には20件の企業が一覧表示されているのでa[id=company_name0]からa[id=company_name19]の20件である。
a[id=company_name0],a[id=company_name1],….,a[id=company_name19]の文字列をつくりたいのでfor文で作成して組み合わせる。
<?php include_once('simplehtmldom_1_5/simple_html_dom.php'); $url = 'http://www.ullet.com/searchd/page/1.html'; $contents = file_get_contents($url); $content = mb_convert_encoding($contents, 'UTF-8', 'auto'); $html = str_get_html($content); $str = ""; for($i= 0; $i < 20; $i++){ $str .= "a[id=company_name" . $i . "]"; if($i != 19){ $str .= ","; } } $result = $html->find($str); foreach($result as $element){ echo "http://www.ullet.com" . $element->href . PHP_EOL; }
実行すると下記20件のURLが取得できる。
http://www.ullet.com/7203.html http://www.ullet.com/7267.html http://www.ullet.com/6178.html http://www.ullet.com/7201.html http://www.ullet.com/9432.html http://www.ullet.com/6501.html http://www.ullet.com/7181.html http://www.ullet.com/9984.html http://www.ullet.com/5020.html http://www.ullet.com/8267.html http://www.ullet.com/8015.html http://www.ullet.com/6758.html http://www.ullet.com/6752.html http://www.ullet.com/8750.html http://www.ullet.com/8002.html http://www.ullet.com/8058.html http://www.ullet.com/9501.html http://www.ullet.com/3382.html http://www.ullet.com/8306.html http://www.ullet.com/6502.html
これを193ページ分、取得する。前回同様に上記のコードを関数にまとめて引数でURLを193回渡して実行する。
<?php include_once('simplehtmldom_1_5/simple_html_dom.php'); function getdata($url){ $contents = file_get_contents($url); $content = mb_convert_encoding($contents, 'UTF-8', 'auto'); $html = str_get_html($content); $str = ""; for($i= 0; $i < 20; $i++){ $str .= "a[id=company_name" . $i . "]"; if($i != 19){ $str .= ","; } } $result = $html->find($str); foreach($result as $element){ echo "http://www.ullet.com" . $element->href . PHP_EOL; } } for($i = 1; $i <=193; $i++){ $url = "http://www.ullet.com/searchd/page/{$i}.html"; getdata($url); }
少し時間がかかるが、3842件のURLが取得できた。この3842件をコピーしてtxtファイルに保存をしておく。
このURLひとつに対して従業員数などを取得するコードを作成して、同じく3842回実行(上記txtファイルからURLを読み込んでループ)する訳であるが、基本的には同じ事なので内容は割愛をする。
途中でエラーが出た項目があったのでその点だけメモを残しておく。
実行をしていく中で詳細ページのURLによってはうまくいく場合もあれば、うまくいかない場合もあった。
うまくいかない場合には下記のエラーが表示される。
Fatal error: Call to a member function find() on boolean in …
調べてみたところSimple HTML DOM Parserの問題であった。解析対象のサイズが大きすぎるとエラーが出てしまうようである。URLごとに多少ファイルサイズが違うようで、エラーが出たり出なかったりした。
simple_html_dom.php の65行目にMAX_FILE_SIZEが600KBと定義されている。
define('MAX_FILE_SIZE', 600000);
これを600000より大きい値に変更すれば解決した。
簡単ではあるがここまでメモしておく。