見出し画像

【PHPでWebスクレイピング入門】PHPからプロキシ経由でInstagramデータを入手する

今回やりたい事として、PHPを使って対象となるInstagramのJSONデータをプロキシサーバーを経由して入手してみたいと思います。

ご存知の通り、Instagramはスクレイピングなどに対して非常に厳しい制限を設けており、少しでも連続したアクセスなどを行うと自分のIPアドレスが一定の期間利用不可能になってしまいます。この制限で、多くのプログラマが頭を悩ませている部分かと思います。

今回の狙いとして、PHPを別途入手するプロキシサーバーを経由し、複数のIPアドレスを切り分けて使う事で、連続してInstagramのデータを入手したいと思います。

注意事項: Instagramはスクレイピングなどを利用規約にて禁止しており、今回の記事ではPythonのお題として取り上げております。これらを利用して運用する事は、利用規約に抵触する可能性が高いので、あくまで自己責任の範囲で行ってください。

まずは環境の準備

今回は特別なAPIなどを使わず、PHPが標準で持っている関数などを使ってJSONデータを入手してみます。

PHPでは、下記のライブラリ「Instagram-API」がとても有名ですが、どうもDMCAに違反していると言う事で、取り下げられてしまっています。(2020年1月30日現在)

https://github.com/mgp25/Instagram-API

スクリーンショット 2020-01-30 午前9.34.22

1. InstagramページからJSONデータを入手する - 通常の場合

Instagramのページ構造として、ユーザーや投稿などに関する情報がJavaScript内にJSON形式で埋め込まれているので、こちらはそのJSONデータを取り出す関数モジュールになります。

function get_json_data($url) {

  $dom = new DOMDocument;
  @$dom->loadHTML(file_get_contents($url));
  $xpath = new DOMXPath($dom);

  $js = $xpath->query('//body/script[@type="text/javascript"]')->item(0)->nodeValue;
  $json = substr($js, strpos($js, '{'), strrpos($js, ';') - strpos($js, '{'));
  $data = json_decode($json, true);

  return $data;

}

2. InstagramページからJSONデータを入手する - プロキシ経由の場合

2.0プロキシサーバーでテストをする

まず最初にプロキシサーバーを入手します。ネットで検索すると、無料で使えるものや有料のものなど、沢山出てくると思います。今回オススメするのは、Blazing SEOが提供するBlazing Proxiesです。こちらは有料タイプですが、安価で専用のIPアドレスがもらえる事、またロケーションを自由に選べる事が特徴です。申し込みの方法など、詳しくはこちらの記事をご覧ください。

今回テストで使用するコードはこちらです。

$url = "https://expressvpn.com/what-is-my-ip";

$dom = new DOMDocument;
@$dom->loadHTML(file_get_contents($url));
$xpath = new DOMXPath($dom);

#var_dump($xpath);

$js = $xpath->query("//p[@class='ip-address']");

foreach ($js as $node)
{
   print("IP Address without Proxy: ".$node->nodeValue."<br>");
   #var_dump($x_path->query(".//nodeValue", $node));
}

まずはプロキシなしでPHPを実行してみます。

IP Address without Proxy: 自分のマシンのパブリックIPアドレス

ここで表示されるのが、現在自分のマシン上のパブリックIPとなります。

次は下記のプロキシありのスクリプトでPHPを実行してみます。まず、下記のラインを先ほど購入したプロキシサーバー情報に置き換えてください。

$PROXY_HOST = "アサインされたプロキシのIPアドレス";
$PROXY_PORT = "ポート番号";
$PROXY_USER = "ユーザー名";
$PROXY_PASS = "パスワード";

$auth = base64_encode("$PROXY_USER:$PROXY_PASS");
stream_context_set_default(
array(
 'http' => array(
  'proxy' => "tcp://$PROXY_HOST:$PROXY_PORT",
  'request_fulluri' => true,
  'header' => "Proxy-Authorization: Basic $auth"
 )
)
);

$dom = new DOMDocument;
@$dom->loadHTML(file_get_contents($url));
$xpath = new DOMXPath($dom);

#var_dump($xpath);

$js = $xpath->query("//p[@class='ip-address']");

foreach ($js as $node)
{
   print("IP Address with Proxy: ".$node->nodeValue."<br>");
   #var_dump($x_path->query(".//nodeValue", $node));
}

そうすると、結果は先ほどの自分のIPアドレスとは異なる、購入したプロキシサーバーのIPアドレスに切り替わっているはずです。

IP Address with Proxy: アサインされたプロキシのIPアドレス

このテストで、PHPをプロキシサーバー経由でアクセスできる事が確認できました!

2.3 プロキシを経由してInstagramのJSONデータを取得する

冒頭にあったスクリプトに、今回のプロキシサーバーを適用した部分を実際に当てはめてみます。

function get_json_data($url) {

 $PROXY_HOST = "アサインされたプロキシのIPアドレス";
 $PROXY_PORT = "ポート番号";
 $PROXY_USER = "ユーザー名";
 $PROXY_PASS = "パスワード";

 $auth = base64_encode("$PROXY_USER:$PROXY_PASS");
 stream_context_set_default(
  array(
   'http' => array(
    'proxy' => "tcp://$PROXY_HOST:$PROXY_PORT",
    'request_fulluri' => true,
    'header' => "Proxy-Authorization: Basic $auth"
   )
  )
 );

 $dom = new DOMDocument;
 @$dom->loadHTML(file_get_contents($url));
 $xpath = new DOMXPath($dom);

 $js = $xpath->query('//body/script[@type="text/javascript"]')->item(0)->nodeValue;
 $json = substr($js, strpos($js, '{'), strrpos($js, ';') - strpos($js, '{'));
 $data = json_decode($json, true);

 return $data;

}

これで、PHPを使い、プロキシサーバー経由でInstagramへ無事にアクセスできる様になりました。

この記事が気に入ったらサポートをしてみませんか?