LoginSignup
2
2

More than 5 years have passed since last update.

GoutteでPOSTの結果からCSVダウンロード

Last updated at Posted at 2016-12-23

やりたかったこと

Goutteで某サイトへログイン、リンクを辿ってCSVファイルをダウンロードする。
以前やったし楽勝だろうと思っていたが、思いの外ハマったので記事にしときます。

読むと分かること

POSTでリンクらしきものを叩き、叩いた結果からCSVを取得する実装方法
(↑本記事とはあまり関係ないですが、POSTになるのは、
内部的にはJavaScriptとかが呼ばれてhiddenでもろもろの値を設定してから、検索したりしているためです)

環境

CentOS release 6.8 (Final)
PHP 5.4.34
Goutte v2.0.4
(いろいろちょい古いです)

Goutteでのダウンロード

  • ぐぐるとよくある例
$client->request('GET', 'http://hoge.com/download.php');
$client->request('GET', 'http://hoge.com/download.csv');

あと、以前私が書いた記事
http://qiita.com/kokushi_yayoi/items/299f62b8fece8b1920d6

 違う、今回はPOSTでダウンロードしたいのだ

実装方法

下記のように実装したところ、今回はPOSTのレスポンスからCSVのテキストを取得できました

download_csv.php
<?php

require_once __DIR__ . "/goutte-v2.0.4.phar";
use Goutte\Client;

$client = new Client();

/*** もろもろ略 ***/
/*** CSVダウンロードボタンのページまでは実装済みで遷移済みです ***/

$result = $client->submit($csv_download_form);
// POSTのレスポンスを取得してます
$csv_download_response = $client->getResponse()->getContent();

// 念のため、読み込みできるかを確認
if ($csv_download_response->isReadable()) {
    $directory_path = './download/';
    // ここにCSVのデータを全部入れてます。
    // read()でレスポンスを読み込むができ、getSize()で結果が何文字だったかが分かるので、全部読み込みしてます
    $response_content = mb_convert_encoding($csv_download_response->read($csv_download_response->getSize()), 'utf8', 'sjis-win');

    $file = new SplFileObject($directory_path.'hoge.csv', 'w');
    $file->fwrite($response_content);
} else {
    echo '読み込みできませんでした';
}

答えを見ればけっこうかんたんです。
ただ、ググっても良い感じの情報にたどり着くのに時間がかかりました。

調査した順序

  1. ログインしてCSVダウンロードの手順は手動で行い、開発ツールを使って、要素を洗い、何が行われているかを調べながら進めます。
  2. 調べた要素通りにログイン→ページ遷移→CSVダウンロードボタン押下までを実装します。上に挙げた以前の記事をご覧ください。
  3. 普通にダウンロードボタン押下まではかんたんに実装できた。以前の通りにCSVに書き出そうとしたら、うまく書き出されない。
  4. 開発ツールでNetworkパネルで調べたところ、今回のサイトはPOSTしていて、以前と同じ実装(GETのレスポンスをゴニョゴニョする)は通用しないことが判明。
  5. とりあえずググるがよくわからないので、地道にNetworkパネルの中身を読み込んで、var_dump()で何が取れているかを確認。
  6. Response HeadersのContent-Dispositionにちゃんとデータが入っていることは確認できたので、ドキュメントにあったread()とgetSize()で当たりをつけて実装してみたら動いた。

答えが載っているドキュメント。
http://docs.guzzlephp.org/en/5.3/streams.html
$client->getResponse()をvar_dumpするとわかりますが、
contentの中にStream型で入っています。

結論

無事POSTで取得するパターンのCSVファイルも取得できました。
スクレイピングをしていると、普段あまり意識していない
RequestとResponseで各項目が何を意味してどういう情報が入っているかを
詳細に知る必要があるのでいい勉強になります。
特に開発ツールのNetworkパネルはめっちゃ有用な情報が詰まってるので、
一度眺めてみると面白いかもしれません。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2