Webサイトの情報をスクレイピングで取得する(前編)

WebRequest関数を使うかWindows APIを使うか

どこかのWebサイトの情報を取得し、MT4に表示したりトレードの判断に使ったりしたいことってありますよね?

恐らく一番多いケースは経済指標や経済ニュースの情報ではないでしょうか?

Webサイトの情報を取得する技術のことをスクレイピングって言いますが、これを使えば実現できます。

ただ、スクレイピングはMQL4の知識だけでは難しく、HTMLを解析する知識(PHP言語を使うのが個人的にはお勧め)も必要になります。

処理の流れとしては、以下のようになります。

  • MQL4側:スクレイピング用のPHP等を呼び出す
  • PHP側:WebサイトのHTMLを解析し、取得したいデータを抜き出してレスポンス
  • MQL4側:レスポンスデータを受け取って後続の処理を実行

PHP言語等に頼らない方法もあります。

  • MQL4側:WebサイトのHTMLを直接根こそぎ取得
  • MQL4側:欲しいデータ部分を頑張って抜き出して後続の処理を実行

一見、後者の方がPHP等の外部技術を使わないし、ステップも少ないしで簡単そうに見えるかもしれませんが、「頑張って」の部分がとても大変です。

しかも、取得データが日本語だと文字コードの関係で文字化けすることがあります。

MT4というかMetaQuotes社はマルチバイト文字のことなんかアウトオブ眼中です。

というわけで、通常は前者の方法を採用することになるかと思います。

PHP等にはHTMLを解析するライブラリがありますし、文字コードもごにょごにょできますからね。

さて、「MQL4側:スクレイピング用のPHP等を呼び出す」には2種類の方法があります。

1つはMT4の組込み関数であるWebRequest関数を使う方法。もう1つはWindows APIを使う方法です。

WebRequest関数には制限あり
WebRequest関数はEAかスクリプトでのみ動作します。インジケーターには使えないので、インジケーターの場合はWindows API一択となります。

どちらも事前設定作業がありまして、前者の場合は、MT4の[ツール]-[オプション]-[エキスパートアドバイザ]タブにある、[WebRequestを許可するURLリスト]にチェックを入れて、PHP等のアクセス先のURL(ドメインまででOK)を入力欄に記述する必要があります。

スクレイピングの準備

後者の場合は、上記画面で[DLLの使用を許可する]にチェックを入れる必要があります。

上記設定が終わったら、MQL4でコードを記述します。例として、YahooファイナンスのFX情報を取得してみましょう。

まずはWebRequest関数の場合です。

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  string headers;
  char   post[];
  char   result[];

  // アクセス先(PHPではなくYahooファイナンスのURLを直接指定することも可能。文字化けしますけどね。)
  string url = "https://autofx100.com/GetYahooFinanceFX.php";

  int res = WebRequest("GET",    // HTTPメソッド
                       url,      // URL
                       NULL,     // cookie
                       NULL,     // リファラ
                       5000,     // タイムアウト
                       post,     // HTTPメッセージ本体
                       0,        // HTTPメッセージサイズ
                       result,   // 応答データ配列
                       headers); // 応答ヘッダ

  if(res == -1){
    // エラー時の処理
  }else{
    string text = CharArrayToString(result);
    Comment(text);
    // 実現したい処理
  }

  return(INIT_SUCCEEDED);
}

続いてWindows APIの場合です。

// Windows APIをインポート
#import "wininet.dll"
int InternetOpenW(string agent, int accessType, string proxyName, string proxyByPass, int flags);
int InternetOpenUrlW(int internetSession, string url, string header, int headerLength, int flags, int context);
int InternetReadFile(int, uchar &arr[], int, int &byte);
int InternetCloseHandle(int winINet);
#import

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  // アクセス先(PHPではなくYahooファイナンスのURLを直接指定することも可能。文字化けしますけどね。)
  string url = "https://autofx100.com/GetYahooFinanceFX.php";

  int inet = InternetOpenW("MetaTrader 4 Terminal", 0, "0", "0", 0);

  if(inet == 0){
    // エラー時の処理
  }else{
    int handle = InternetOpenUrlW(inet, url, NULL, 0, 0, 0);

    string text = "";
    int    byteSize = 0;
    uchar  receive[1024];

    // 1024バイトずつHTMLデータを取得して、textに追記
    while(InternetReadFile(handle, receive, 1024, byteSize)){
      if(byteSize <= 0) break;
      text += CharArrayToString(receive, 0, byteSize, CP_ACP);
    }

    // メモリのお掃除
    InternetCloseHandle(handle);
    InternetCloseHandle(inet);
  }

  return(INIT_SUCCEEDED);
}

上記コードをティックごとに実行してしまう(OnTickで呼び出す)と、ティックごとにWebサーバーにアクセスすることになるので、Webサーバー側は「攻撃を受けた!」と判断する可能性が高いです。

OnTickやOnTimerで実行する場合は、1分おきに実行する等の考慮が必要です。

上記どちらの場合もスクレイピング結果はtextに格納されます。

ちなみに、上記をコンパイルして実行してもGetYahooFinanceFX.phpは未作成なので動きません。

次回の後編ではGetYahooFinanceFX.phpの中身についてご説明いたします。

MT4の無料プログラミング講座

メルマガ登録して、MT4のプログラミング講座を無料で受けちゃおう!

超豪華プレゼントも盛りだくさん♪

MT4プログラミングを習得すると、オリジナルEA運用、作成代行、商品販売等、複数の収入源を手に入れられるよ。副業に最適だね!

↓↓↓ 詳細はこちら ↓↓↓

アイキャッチ

>

エターナル・パートナーPRO ~MT4裁量トレード支援ツール~ 「MT4は裁量トレーダーに優しくない」そう思ったことありませんか?もっと快適にトレードするための強力な売買ツールが必要だと考え、開発したのが「エターナル・パートナーPRO」です。元々は自分自身のために開発したツールですので、手抜き無しのガチものです。既に200名近い方に手に取っていただき、喜びの声が続々と届いております。ぜひご覧ください!

CTR IMG