【PHP】Cookie を保存/送信して認証が必要なページをスクレイピングしてみる【curl】

こんにちは。
先日、CakePHP で作られた外部システムからデータを引っ張ってくる必要がありました。
ただ、データ取得用の API 等が用意されているわけでもなかったため、curl で叩いてデータを引っ張ってくることにします。

最初のログインページの認証後に Cookie を維持する必要があったので、その処理を PHP で実装してみます。

コード

PHPには cURL 関数が用意されているのでありがたく使わせて頂きます。

<?php

class PHPCurl {
    
    private $getCookieUrl;
    private $targetUrl;
    private $username;
    private $password;
    private $saveCookieFile;

    /**
     * コンストラクタ
     * 
     * @param string $getCookieUrl Cookie取得用のURL
     * @param string $targetUrl    CurlのターゲットURL
     * @param string $username     ログイン情報(ユーザ名)
     * @param string $password     ログイン情報(パスワード)
     */
    public function __construct($getCookieUrl, $targetUrl, $username, $password){
        $this->getCookieUrl = $getCookieUrl;
        $this->targetUrl = $targetUrl;
        $this->username = $username;
        $this->password = $password;
        $this->saveCookieFile = stream_get_meta_data($fp = tmpfile());
    }

    /**
     * Cookie取得用のメソッド
     */
    public function getCookie(){
        $data = array(
            'data[User][username]' => $this->username,
            'data[User][password]' => $this->password,
        );

        $curl = curl_init($this->getCookieUrl);
        curl_setopt($curl, CURLOPT_POST, TRUE);
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));

        curl_setopt($curl, CURLOPT_COOKIEJAR, $this->saveCookieFile['uri']);
        curl_setopt($curl, CURLOPT_COOKIEFILE, $this->saveCookieFile['uri']);
        curl_exec($curl);
        curl_close($curl);
    }

    /**
     * コンテンツ取得用のメソッド
     * 
     * @return string HTMLコンテンツ
     */
    public function getContent(){
        $curl = curl_init($this->targetUrl);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_COOKIEFILE, $this->saveCookieFile['uri']);
        $result = curl_exec($curl);
        curl_close($curl);

        return $result;
    }
}

$curlInfo = new PHPCurl('https://xxxxxx.xxx/login', 'https://xxxxxx.xxx/target', 'finger', 'ease');

$curlInfo->getCookie();
$content = $curlInfo->getContent();

echo $content;

※ POST の bodyデータ は適宜置き換えてくださいね。
あとは必要なデータをパースするだけです。

おまけ

curl だったら下記 2 行だけなんですよね。

curl -c ./cookie.txt -d "data[User][username]=finger" -d "data[User][password]=ease" "https://xxxxxx.xxx/login"
curl -b ./cookie.txt "https://xxxxxx.xxx/target"