初めに、伝えておきます。
この記事では、スクレイピング自体に関する説明はしていません。
つまり、スクレイピングに関しては中級者、上級者向けの内容となります。
すでにスクレイピングを経験済みの人が対象です。
さらに言えば、アクセス過多でBANされた経験があれば、なおGOODです。
そのような人向けの内容です。
もちろん、スクレイピングに関する法的知識があることも前提です。
最近では、私もBANされる頻度はかなり減りました。
その理由は、アクセス制限を受けないように調整しているからです。
数秒間隔でアクセスするなどの調整ですね。
ただ、それだと時間がかかるのですよね。。。
データ分析を行う場合、その部分がボトルネックになりがちです。
時間のかかることが、スクレイピングを行う上での課題でしょうか。
でも、この課題をクリアできる方法があるのです。
この記事では、その方法について説明していきます。
本記事の内容
- プロキシ経由でサイトへアクセスするメリット
- 【実証】PHPでプロキシ経由のアクセスを行う
- プロキシ経由でスクレイピングを行う
プロキシ経由でサイトへアクセスするメリット
メリットを説明する前に、プロキシを簡単に説明します。
プロキシは、あなた(あなたのサーバー)の代わりにサイトにアクセスしてくれるのです。
代わりにアクセスして、 プロキシはサイトの情報をあなたに渡してくれます。
だから、サイトはあなたがアクセスしてきたことを知りません。
サイトが認識できるIPアドレスは、あなたのものではなく、プロキシのIPアドレスなのです。
また、サイトはIPアドレスであなたの行動を監視しています。
同じIPアドレスから、短時間に大量のアクセスがあるかどうかをチェックしているのです。
しかし、プロキシ経由でサイトにアクセスすれば、監視もチェックもできません。
もちろん、コロコロとプロキシを変更することが前提です。
そうなると、サイト側はあなたにアクセス禁止・制限を課すことはできません。
以上により、スクレイピングが自由にできるのです。
これが、プロキシ経由でサイトへアクセスするメリットです。
ただし、サーバーにダメージを与えるアクセスは厳禁です。
夜間や早朝など、サイトのサービスに迷惑をかけないことは大前提です。
【実証】PHPでプロキシ経由のアクセスを行う
プロキシ経由のアクセスを実証します。
実際にプロキシ経由でアクセスした場合、アクセス先でのアクセス状況を確認します。
基本的には、IPアドレスで管理しているはずです。
IPアドレスが実際に変わるのかどうか?
プロキシ経由だとバレるのかどうか?
これらを中心に確認していきます。
「彼を知り己を知れば百戦殆うからず」
スクレイピングにおいても、ためになる言葉です。
検証用コード
アクセス先
次のコードを記述したto.phpを作成します。
そして、https://○○○/to.phpでアクセスできるようにします。
<?php echo "【HTTP_USER_AGENT】" . $_SERVER['HTTP_USER_AGENT']; echo "<br />"; echo "【REMOTE_ADDR】" . $_SERVER['REMOTE_ADDR']; echo "<br />"; echo "【HTTP_VIA】" . $_SERVER['HTTP_VIA']; echo "<br />"; echo "【HTTP_X_FORWARDED_FOR】" . $_SERVER['HTTP_X_FORWARDED_FOR']; echo "<br />"; echo "【HTTP_CLIENT_IP】" . $_SERVER['HTTP_CLIENT_IP']; echo "<br />"; // 要求元(アクセス元)IPの抽出 $from_ip = ""; if( isset($_SERVER['HTTP_CLIENT_IP']) ) { $from_ip = $_SERVER['HTTP_CLIENT_IP']; } elseif( isset($_SERVER['HTTP_X_FORWARDED_FOR']) ) { $ip_list = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']); $from_ip = current($ip_list); } echo "【FROM_IP】" . $from_ip; echo "<br />"; ?>
アクセス元の情報を出力するプログラムです。
FROM_IPは環境変数ではなく、適当に設定した変数です。
プロキシ経由におけるアクセス元IPを格納しています。
でも、入るかどうかもプロキシ次第のようですね。
では、サーバー環境変数について説明しておきます。
HTTP_USER_AGENT | ユーザーエージェント |
REMOTE_ADDR | ユーザーのIPアドレス |
HTTP_VIA | プロキシソフトのバージョン名(表示されないソフトもある) |
HTTP_X_FORWARDED_FOR | プロキシのIPアドレス(多段プロキシの場合は「,」 で区切られたリスト) |
HTTP_CLIENT_IP | 要求元(アクセス元)のIPアドレス |
プロキシソフトにより、HTTP_X_FORWARDED_FORやHTTP_CLIENT_IPに値が入ったり入らなかったり。
つまり、あまり信用できないということですね。
でも、今回は検証なので特に問題にはなりません。
アクセス元
次のコードを記述したfrom.phpを作成します。
そして、https://▲▲▲/from.phpでアクセスできるようにします。
<?php $url = "アクセス先URL";//←【1】 $ua = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, $ua); // プロキシの設定 // CURLOPT_HTTPPROXYTUNNELで制御したかったが、機能していないので今回は無視 curl_setopt($ch, CURLOPT_PROXYPORT, 'プロキシのポート');//←【2】 curl_setopt($ch, CURLOPT_PROXY, 'プロキシのURL');//←【3】 $html = curl_exec($ch); curl_close($ch); echo $html; ?>
【1】~【3】は適宜変更してください。
【1】は、https://○○○/to.phpとなります。
検証:プロキシ経由なし
from.phpは以下に設定
// プロキシの設定 curl_setopt($ch, CURLOPT_PROXYPORT, '');//←【2】 curl_setopt($ch, CURLOPT_PROXY, '');//←【3】
そして、https://▲▲▲/from.phpにアクセスします。
結果は、以下。
【HTTP_USER_AGENT】Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 【REMOTE_ADDR】133.167.77.58 【HTTP_VIA】 【HTTP_X_FORWARDED_FOR】 【HTTP_CLIENT_IP】 【FROM_IP】
プロキシを経由しないアクセスなので、妥当な結果です。
【REMOTE_ADDR】は、from.phpを設置したサーバーのIPアドレスとなります。
ちなみに、133.167.77.58はこのブログが動いているサーバーのIPです。
検証:プロキシ経由あり
from.phpは以下に設定
// プロキシの設定 curl_setopt($ch, CURLOPT_PROXYPORT, '80');//←【2】 curl_setopt($ch, CURLOPT_PROXY, 'http://88.199.21.76');//←【3】
そして、https://▲▲▲/from.phpにアクセスします。
結果は、以下。
【HTTP_USER_AGENT】Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 【REMOTE_ADDR】88.199.21.76 【HTTP_VIA】 【HTTP_X_FORWARDED_FOR】 【HTTP_CLIENT_IP】 【FROM_IP】
完全(PHPで判別できるレベルでは)になりすましたケースですね。
【REMOTE_ADDR】には、プロキシのIPが入っています。
今回の検証では、以下で探したプロキシを利用しました。
無料で使えるプロキシ一覧
http://www.freeproxylists.net/ja/
あと、何度も匿名性の高くないプロキシで試しました。
しかし、「完全なりすまし」という結果ばかりでした。
to.phpで出力する予定だった「HTTP_VIA」を拝むことは一度もできませんでした。
まあ、当然と言えば当然かもしれません。
そもそも、プロキシを経由するのは、匿名性を確保したいからですので。
プロキシ経由でスクレイピングを行う
プロキシ経由でアクセスができることを確認しました。
かつ、匿名性を確保した「なりすまし」のアクセスです。
では、from.phpを改良して、実際にプロキシ経由でスクレイピングをしてみます。
$url = "アクセス先URL";//←【1】
スクレイピングしたいページのURLに変更。
どんなページでもOKです。
なぜなら、titleタグをスクレイピングするだけですので。
echo $html;
この部分を次のコードに変更。
ここでは、簡単にスクレイピングしたいので正規表現を使います。
$pattern = '/<title>(.*?)<\/title>/is'; if( @preg_match_all($pattern, $html, $matches)){ $v_tmp_str = $matches[1][0]; echo $v_tmp_str; }
私は、以下のように変更しました。
<?php $url = "https://qiita.com/Octoparse_Japan/items/3fde94e6da5305498e5f";//←【1】 $ua = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERAGENT, $ua); // プロキシの設定 curl_setopt($ch, CURLOPT_PROXYPORT, '80');//←【2】 curl_setopt($ch, CURLOPT_PROXY, 'http://88.199.21.76');//←【3】 $html = curl_exec($ch); curl_close($ch); $pattern = '/<title>(.*?)<\/title>/is'; if( @preg_match_all($pattern, $html, $matches)){ $v_tmp_str = $matches[1][0]; echo $v_tmp_str; } ?>
そして、https://▲▲▲/from.phpにアクセスします。
結果は、以下。
プロキシ経由で見事にスクレイピングが成功していますね。
まとめ
プロキシ経由でサイトへアクセスするメリットを説明しました。
そして、PHPでプロキシを用いてサイトへアクセスしました。
そのコードを載せています。
さらには、実際にプロキシ経由でスクレイピングする方法も説明しました。
そのコードも載せています。
この記事の内容に従っていけば、簡単にプロキシ経由でスクレイピングが可能です。
ただし、何度も言いますが、節度をもったスクレイピングを心がけてください。