前記事で、Heroku で立ち上げていたウェブスクレイピングのための Node.js サーバーの代わりをレンタルサーバー内の pyhton でやってみたのですが、よくよく考えれば、やっていることがスクレイピングというほどのことでもありませんので、php の正規表現で出来ないだろうかと試してみました。
01Filmarks のマイページの1記事の url を取り出す
やっていることはタイトル通り、映画のレビューサイトの各記事と Filmarks のマイページのレビューとをリンクさせようということです。それを python でやってみたのが前記事です。
現在はまだ Heroku を使っているのですが、実装しているのは次のサイトの各記事の本文下の「Filmarks」ボタンです。
ですので、9月18日現在では、Ajax -> Node.js サーバー -> Ajax の流れですが、上の記事ではウェブページから Ajax -> php -> python -> php ->Ajax という流れを試しているということです。
結果としては最も時間がかかる作業で
/movies/69200?mark_id=40419254
処理時間:8.9638450145721秒
ということでした。上が取り出してきた url、下がかかった時間です。で、これを php の正規表現でやってみようということです。
02php の正規表現のほうが速い
結果からいいますと、php の正規表現のほうが速かったです。同じ作業の結果が次のとおりです。
/movies/69200?mark_id=40419254
処理時間:7.7281849384308秒
どちらのデータもサーバーの稼働状況がありますので数回試して一番速かったデータです。また、やっていることはスプレイピングというほどのことではなく、ただクローリングして必要なデータを取り出してくるだけの作業ですので比較そのものにあまり意味はないかも知れません。
試したコードは次のとおりです。
functions.php
/* Javascript の読み込みと php から変数 ajax_url を Javascript に渡す */
add_action( 'wp_enqueue_scripts', 'sample_enqueue_scripts' );
function sample_enqueue_scripts() {
if(is_single()){
wp_enqueue_script( 'filmarks-js', get_stylesheet_directory_uri() . '/lib/js/get-filmarks.js', '', '', true );
wp_localize_script( 'filmarks-js', 'wp_ajax', array(
'ajax_url' => admin_url( 'admin-ajax.php' )
) );
}
}
/* Javascript から Ajax で呼ばれ、Filmarks からデータを取得し echo で返す */
add_action('wp_ajax_get_filmarks', 'get_filmarks_page');
add_action('wp_ajax_nopriv_get_filmarks', 'get_filmaraks_page');
function get_filmarks_page(){
$start = microtime(true);
$title = $_POST['title'];
$url = 'https://filmarks.com/users/ausnichts'; // 私のマイページurl
$mypage = file_get_contents($url);
preg_match('/"c-pagination__last".*href="\/users\/ausnichts\?page=(\d+)/s', $mypage, $matches);
$page = $matches[1];
for($i=1; $i<=$page; $i++){
$u = $url . '?page=' . $i;
$nowpage = file_get_contents($u);
$pattern = '/<a href="(\/movies\/\d+\?mark_id=\d+)">' . $title . '/s';
if(preg_match($pattern, $nowpage, $matches)){
echo $matches[1] . PHP_EOL;
$end = microtime(true);
echo '処理時間:'.($end - $start)."秒" . PHP_EOL;
die();
}
}
}
考え方は前記事と同じで、マイページのトップページでページ数を取得し、その回数だけループさせ、各ページで必要なデータが見つかればその時点でデータを返して終了しています。
Javascript
document.addEventListener('DOMContentLoaded', () => {
const params = new URLSearchParams();
params.append('action', 'get_filmarks');
params.append('title', document.title);
const opt = {
method: 'post',
body: params
}
fetch(wp_ajax.ajax_url, opt)
.then(response => response.text())
.then(text => console.log(text))
.catch(error => console.error(error));
});
Javascript は Fetch を使っています。
ということで、処理時間はほぼ同じくらいですので、この件は php で完了させたほうがよさそうです。