AM2
Андрей

 
Уровень 30

  Торгую в компаниях:


Группа "Программирование на MQL"

Рейтинг 272



Парсинг страницы сайта и MQL4

На самом простом примере рассмотрим, как можно использовать данные со страницы сайта в собственном эксперте. Для тех кто желает изучить эту тему более углубленно, есть следующие материалы:

www.mql5.com/ru/code/7089
www.mql5.com/ru/code/12768
www.mql5.com/ru/code/10366
www.mql5.com/ru/articles/73

Будем считывать данные со всеми нами любимой страницы: opentraders.ru/

Задание будет следующим: как только уровень пользователя shulgindv поднимется на одну строчку, советник откроет покупку объемом 0.1 лота.
Такого задания вы мне еще не присылали! Не правда ли? :D 

Необходимую нам циферку нужно будет стащить отсюда:



Чтобы достичь нужного результата, сохраним страницу в текстовом формате. На странице будем искать вхождение: «level-66»



Желательно чтобы оно было уникальным, таким образом будет проще работать со строками. Во входных переменных, укажем адрес сайта и нужное вхождение:


input string URL="http://opentraders.ru/";
input string SubString="level-66";


Присоединим библиотеку: «wininet.dll». С ее помощью будем открывать и считывать страницу в строку.


#import "wininet.dll"
int InternetAttemptConnect(int x);
int InternetOpenW(string sAgent,int lAccessType,string sProxyName="",string sProxyBypass="",int lFlags=0);
int InternetOpenUrlW(int hInternetSession,string sUrl,string sHeaders="",int lHeadersLength=0,int lFlags=0,int lContext=0);
int InternetReadFile(int hFile,int &sBuffer[],int lNumBytesToRead,int &lNumberOfBytesRead[]);
int InternetCloseHandle(int hInet);
#import


Воспользуемся готовой функцией для импорта веб-страницы в текстовую строку:


//+------------------------------------------------------------------+
// Скачивает исходный код страницы HTML  в текстовую переменную      |
//                и возвращает как результат                         |
//+------------------------------------------------------------------+
string ReadHTML()
  {
   if(!IsDllsAllowed())
     {
      Alert("Необходимо в настройках разрешить использование DLL");
      return("");
     }
   int rv = InternetAttemptConnect(0);
   if(rv != 0)
     {
      Alert("Ошибка при вызове InternetAttemptConnect()");
      return("");
     }
   int hInternetSession=InternetOpenW("Microsoft Internet Explorer",0,"","",0);
   if(hInternetSession<=0)
     {
      Alert("Ошибка при вызове InternetOpenW()");
      return("");
     }
   int hURL=InternetOpenUrlW(hInternetSession,URL,"",0,0,0);
   if(hURL<=0)
     {
      Alert("Ошибка при вызове InternetOpenUrlW()");
      InternetCloseHandle(hInternetSession);
      return("");
     }
   int cBuffer[256];
   int dwBytesRead[1];
   string TXT="";
   while(!IsStopped())
     {
      bool bResult=InternetReadFile(hURL,cBuffer,1024,dwBytesRead);
      if(dwBytesRead[0]==0)
         break;
      string text = "";
      string text0= "";
      for(int i=0; i<256; i++)
        {
         text0=CharToStr((char)(cBuffer[i]&0x000000FF));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

         text0=CharToStr((char)(cBuffer[i]>>(8  &0x000000FF)));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

         text0=CharToStr((char)(cBuffer[i]>>(16  &0x000000FF)));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

         text0=CharToStr((char)(cBuffer[i]>>(24  &0x000000FF)));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

        }
      TXT=TXT+text;
      Sleep(1);
     }
   InternetCloseHandle(hInternetSession);
   return(TXT);
  }
//+------------------------------------------------------------------+


С уже готовой функцией, реализовать нашу задачу можно в 2 строки:


   int sf=StringFind(s,SubString);
   string level=StringSubstr(s,sf+7,2);


Ниже представлен целиком весь код эксперта:


//+------------------------------------------------------------------+
//|                                                       Parser.mq4 |
//|                                              Copyright 2016, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, AM2"
#property link      "http://www.forexsystems.biz"
#property version   "1.00"
#property strict

#import "wininet.dll"
int InternetAttemptConnect(int x);
int InternetOpenW(string sAgent,int lAccessType,string sProxyName="",string sProxyBypass="",int lFlags=0);
int InternetOpenUrlW(int hInternetSession,string sUrl,string sHeaders="",int lHeadersLength=0,int lFlags=0,int lContext=0);
int InternetReadFile(int hFile,int &sBuffer[],int lNumBytesToRead,int &lNumberOfBytesRead[]);
int InternetCloseHandle(int hInet);
#import

input string URL="http://opentraders.ru/";
input string SubString="level-66";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
// Скачивает исходный код страницы HTML  в текстовую переменную      |
//                и возвращает как результат                         |
//+------------------------------------------------------------------+
string ReadHTML()
  {
   if(!IsDllsAllowed())
     {
      Alert("Необходимо в настройках разрешить использование DLL");
      return("");
     }
   int rv = InternetAttemptConnect(0);
   if(rv != 0)
     {
      Alert("Ошибка при вызове InternetAttemptConnect()");
      return("");
     }
   int hInternetSession=InternetOpenW("Microsoft Internet Explorer",0,"","",0);
   if(hInternetSession<=0)
     {
      Alert("Ошибка при вызове InternetOpenW()");
      return("");
     }
   int hURL=InternetOpenUrlW(hInternetSession,URL,"",0,0,0);
   if(hURL<=0)
     {
      Alert("Ошибка при вызове InternetOpenUrlW()");
      InternetCloseHandle(hInternetSession);
      return("");
     }
   int cBuffer[256];
   int dwBytesRead[1];
   string TXT="";
   while(!IsStopped())
     {
      bool bResult=InternetReadFile(hURL,cBuffer,1024,dwBytesRead);
      if(dwBytesRead[0]==0)
         break;
      string text = "";
      string text0= "";
      for(int i=0; i<256; i++)
        {
         text0=CharToStr((char)(cBuffer[i]&0x000000FF));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

         text0=CharToStr((char)(cBuffer[i]>>(8  &0x000000FF)));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

         text0=CharToStr((char)(cBuffer[i]>>(16  &0x000000FF)));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

         text0=CharToStr((char)(cBuffer[i]>>(24  &0x000000FF)));
         if(text0!="\r") text=text+text0;
         else dwBytesRead[0]--;
         if(StringLen(text)==dwBytesRead[0]) break;

        }
      TXT=TXT+text;
      Sleep(1);
     }
   InternetCloseHandle(hInternetSession);
   return(TXT);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   int r=0;
   string s=ReadHTML();
   int sf=StringFind(s,SubString);
   string level=StringSubstr(s,sf+7,2);
   
   if(StringToInteger(level)>66 && OrdersTotal()<1) 
   r=OrderSend(NULL,0,0.1,NormalizeDouble(Ask,Digits),100,0,0,"",0,0,Lime);
   
   Comment("\n Начало подстроки: ",sf,
           "\n Уровень: ",level);
  }
//+------------------------------------------------------------------+



Когда уровень пользователя достигнет 67, эксперт откроет покупку и выглядеть это будет примерно так:



П.С. По готовому примеру, создавать подобные вещи значительно проще чем все искать и писать с нуля. У меня в целом ушло наверное часов 6 чтобы все это раскопать, соединить и написать, даже при том что реализация простейшая.

Скачать советник: www.opentraders.ru/downloads/1261/
  • +5
  • Просмотров: 15312
  • 21 июля 2016, 12:00
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Программирование на MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
Делаем простейший копировщик сделок
Следующая запись в группе  
Манименеджмент. Лот от риска на стоп.
18 июля 2016
26 июля 2016

Комментарии (8)

+
+2
Задание будет следующим: как только уровень пользователя shulgindv поднимется на одну строчку, советник откроет покупку объемом 0.1 лота.

офигенный советник, надо на мониторинг ставить <img src='http://opentraders.ru/templates/skin/g6h/images/smilies/002.gif' alt=' :) '>&nbsp; *good* 
Редактирован: 21 июля 2016, 12:15
avatar

  41  Bishop Сообщений: 5447 - АЛЬФАХАМЕЦ-Машковод

  • 21 июля 2016, 12:14
+
0
Ты его еще ни в тестере ни в реале не протестировал *boss*  :D 
avatar

  24  Oxy Сообщений: 3279 - ..ιllιlι.lι.ιllι.ιlι..

  • 21 июля 2016, 13:40
+
0
Здесь просто общий принцип. До сегодняшнего дня представления не имел как парсинг делать, а сейчас хоть что то стало проясняться. Если ты заметила, чтобы советник сработал нужно искать вхождение level-6 и от него уже считать уровень, иначе когда уровень изменится в коде HTML будет «level-67». Или если нет «level-66», то значит Шульгин подрос :) 
Редактирован: 21 июля 2016, 15:17
avatar

  30  AM2 Автор Сообщений: 11172 - Андрей

  • 21 июля 2016, 15:06
+
0
Добрый день.
Очень клево!!! Но что то с друн=гих сайтов ерунду выдает(((разбераемся
А подскажите как сделать задержку опроса сайта, например столько то секунд?
спасибо
avatar

  3  LichSL Сообщений: 4

  • 16 сентября 2016, 08:16
+
0
Очень клево!!! Но что то с друн=гих сайтов ерунду выдает


Только вчера с инвестинг котировки вытаскивал. С лмакс напрямую не получилось.

А подскажите как сделать задержку опроса сайта, например столько то секунд?


Sleep(5000);
попробуйте

avatar

  30  AM2 Автор Сообщений: 11172 - Андрей

  • 16 сентября 2016, 08:26
+
0
Да работает, но как заставить понимать русские уникальные надписи.
И еще вопрос если между уникальным именем и искомой величиной несколько строк (на следующей строке) как высчитать смещение… у меня выходит большие цифры, как будто он не в тхт файле отсчитывает, а из htm или как правильно я не знаю.

Короткая сделка
1.00 лотов
15

Хммм вставил в сообщение часть, а он его переиначил(((
Редактирован: 16 сентября 2016, 09:08
avatar

  3  LichSL Сообщений: 4

  • 16 сентября 2016, 09:04
+
0
а возможно ли сделать чтобы из МТ было можно совершать действия на странице… к примеру на веб версии бинарных опционов?
avatar

  7  Kudryashov Сообщений: 120

  • 26 января 2017, 23:35
+
0
Не открывает страницы https:// (SSL).
Подскажите как работать с такими страницами?
Возможно ли это?
avatar

  0  Earring Сообщений: 1

  • 6 марта 2017, 10:38

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий
Начать торговлю с Альпари