Сейчас на форуме: jinoweb, bartolomeo, rmn (+4 невидимых)

 eXeL@B —› Программирование —› C++ - получить код html-страницы
Посл.ответ Сообщение


Ранг: 216.9 (наставник), 85thx
Активность: 0.310.15
Статус: Участник
X-Literator

Создано: 28 мая 2014 18:45 · Поправил: Crawler
· Личное сообщение · #1

Суть вопроса в следующем:

пишу парсер выдачи Google, пока добрался только до получения html-страницы по запросу. Пробую получить при помощи функций из ws2_32.lib (OpenURL и т.д). Естественно, вместо нормальной выдачи получаю страницу с кучей javascript-функций.

А хочется, чтобы в выдаче была именно страница с результатами поискового запроса.

Может быть, есть где-то примеры, на которые можно ориентироваться? Вроде бы, это можно сделать с помощью CppWebBrowser, но не нашел примеров именно с получением кода динамической веб-страницы.

В программировании под веб я полный ноль, так что буду благодарен за любую помощь и - особенно - за примеры (если можно, то без GUI, просто хочется получить код страницы куда-нибудь в строковую переменную)

Заранее спасибо.

Кому интересно, код, который нашел и использую сейчас я, выглядит так:

Code:
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <windows.h>
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #pragma comment(lib, "ws2_32.lib")
  7.  
  8. char* OpenURL(char *url) {
  9.     WSADATA lpWSAData;
  10.     SOCKET s;
  11.  
  12.     // Проверим на правильность введенный адрес.
  13.     // Он должен начинаться с "http://"
  14.     if (memcmp(url,"HTTP://",7)!=0 && memcmp(url,"http://",7)!=0) return(NULL);
  15.     url+=7;
  16.  
  17.     // Инициализация библиотеки Ws2_32.dll.
  18.     if (WSAStartup(MAKEWORD(1,1),&lpWSAData)!=0) return(NULL);
  19.  
  20.  
  21.     // Получим имя хоста, номер порта и путь ----------------------------
  22.  
  23.     char *http_host=_strdup(url); // Имя хоста (HTTP_HOST)
  24.     int port_num=80; // Номер порта по умолчанию (HTTP_PORT)
  25.     char *http_path=NULL; // Путь (REQUEST_URI)
  26.  
  27.     char *pch=strchr(http_host,':');
  28.     if (!pch) {
  29.         pch=strchr(http_host,'/');
  30.         if (pch) {
  31.             *pch=0;
  32.             http_path=_strdup(pch+1);
  33.             }
  34.         else http_path=_strdup("");
  35.         }
  36.     else {
  37.         *pch=0;pch++;
  38.         char *pch1 = strchr(pch,'/');
  39.         if (pch1) {
  40.             *pch1=0;
  41.             http_path=_strdup(pch1+1);
  42.             }
  43.         else http_path=_strdup("");
  44.  
  45.         port_num = atoi(pch);
  46.  
  47.         if (port_num==0) port_num = 80;
  48.         }
  49.  
  50.     // Поучаем IP адрес по имени хоста
  51.     struct hostent* hp;
  52.     if (!(hp=gethostbyname(http_host))) {
  53.         free(http_host);
  54.         free(http_path);
  55.         return(NULL);
  56.         }
  57.  
  58.     // Открываем сокет
  59.     s=socket(AF_INET, SOCK_STREAM, 0);
  60.     if (s==INVALID_SOCKET) {
  61.         free(http_host);
  62.         free(http_path);
  63.         return(NULL);
  64.         }
  65.  
  66.     // Заполняем структуру sockaddr_in
  67.     struct sockaddr_in ssin;
  68.     memset ((char *)&ssin, 0, sizeof(ssin));
  69.     ssin.sin_family = AF_INET;
  70.     ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];
  71.     ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];
  72.     ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];
  73.     ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];
  74.     ssin.sin_port = htons(port_num);
  75.  
  76.     // Выводим IP адрес хоста, с которым будем соединятся
  77.     printf("Conecting to %d.%d.%d.%d...",(unsigned char)hp->h_addr[0],
  78.                                          (unsigned char)hp->h_addr[1],
  79.                                          (unsigned char)hp->h_addr[2],
  80.                                          (unsigned char)hp->h_addr[3]);
  81.  
  82.     // Соединяемся с хостом
  83.     if (connect(s, (sockaddr *)&ssin, sizeof(ssin))==-1) {
  84.         free(http_host);
  85.         free(http_path);
  86.         printf("Error\n");
  87.         return(NULL);
  88.         }
  89.     printf("Ok\n");
  90.  
  91.     // Формируем HTTP запрос
  92.     char *query=(char*)malloc(2048);
  93.  
  94.     strcpy(query,"GET /");
  95.     strcat(query,http_path);
  96.     strcat(query," HTTP/1.0\nHost: ");
  97.     strcat(query,http_host);
  98.     strcat(query,"\nUser-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
  99.     strcat(query,"\nAccept: */*\n\n");
  100.  
  101.  
  102.     // Выводим HTTP запрос
  103.     printf("%s",query);
  104.  
  105.     // Отправляем запрос серверу
  106.     int cnt=send(s,query,strlen(query),0);
  107.  
  108.     // Освобождаем память
  109.     free(http_host);
  110.     free(http_path);
  111.     free(query);
  112.  
  113.     // Проверяем, не произошло ли ошибки при отправке запроса на сервер
  114.      if (cnt==SOCKET_ERROR) return(NULL);
  115.  
  116.     cnt=1;
  117.  
  118.     // Получаем ответ с сервера ---------------------------------
  119.  
  120.     int size=1024*1024; // 1Mb
  121.     char *result=(char*)malloc(size);
  122.     strcpy(result,"");
  123.     char *result_ptr=result;
  124.  
  125.     while (cnt!=0 && size>0) {
  126.         cnt=recv (s, result_ptr, sizeof(size),0);
  127.         if (cnt>0) {
  128.             result_ptr+=cnt;
  129.             size-=cnt;
  130.             }
  131.         }
  132.     *result_ptr=0;
  133.  
  134.     // Деинициализация библиотеки Ws2_32.dll
  135.     WSACleanup();
  136.  
  137.     return(result);
  138.     }
  139.  
  140. int main(void) {
  141.  
  142.  
  143.          FILE *pFile;
  144.          if ((pFile = fopen ("C:\temp\index.html","wb"))==NULL) return -1;
  145.  
  146.     char *result = OpenURL ( "http://www.google.ru/?newwindow=1&q=soulbreaker#newwindow=1&q=soulbreaker" );
  147.  
  148.     if (result) {
  149.         printf("%s",result);
  150.                  fprintf (pFile, "%s",result);
  151.                  
  152.         free(result);
  153.         }
  154.     else {
  155.         printf("Error # WSABASEERR+%d\n",WSAGetLastError()-WSABASEERR);
  156.         }
  157.          getchar();
  158.          fclose (pFile);
  159.          return 0;
  160.     }


-----
Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей.




Ранг: 3.5 (гость), 3thx
Активность: 0.010
Статус: Участник

Создано: 28 мая 2014 19:07
· Личное сообщение · #2

Посмотрите в сторону Google Web Search API
https://developers.google.com/web-search/docs/
Раздел: Flash and other Non-Javascript Environments

Там пишут, что он устарел, и его не рекомендуют использовать. Но пока работает.

| Сообщение посчитали полезным: Crawler

Ранг: 221.3 (наставник), 135thx
Активность: 0.190.07
Статус: Участник

Создано: 28 мая 2014 19:07
· Личное сообщение · #3

НА цпп сам перепишешь

Code:
  1. function Get(const URL: String): THTTPResponse;
  2.          //--------------------------------------------------
  3.          function DelHttp(URL: String): String;
  4.          begin
  5.            if Pos('http://', URL) > 0 then Delete(Url, 1, 7);
  6.          Result := Copy(Url, 1, Pos('/', Url) - 1);
  7.          if Result = '' then Result := URL;
  8.          end;
  9.          //--------------------------------------------------
  10.  
  11. const
  12.   HTTP_PORT = 80;
  13.   CLRF = #13#10;
  14.   Header = 'Content-Type: application/x-www-form-urlencoded' + CLRF;
  15.  
  16. var
  17.   FSession, FConnect, FRequest: HINTERNET;
  18.   FHost, FScript: String;
  19.   Ansi: PAnsiChar;
  20.   Buff: array [0..1023] of Char;
  21.   BytesRead: Cardinal;
  22.   Status, Len, Index: DWORD;
  23. begin
  24.   Result.Status := 0;
  25.   Result.Payload := '';
  26.   FHost := DelHttp(Url);
  27.   FScript := Url;
  28.   Delete(FScript, 1, Pos(FHost, FScript) + Length(FHost));
  29.  
  30.   FSession := InternetOpen('DMFR', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  31.   if not Assigned(FSession) then Exit;
  32.   try
  33.     FConnect := InternetConnect(FSession, PChar(FHost), HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
  34.     if not Assigned(FConnect) then Exit;
  35.     try
  36.       Ansi := 'text/*';
  37.       FRequest := HttpOpenRequest(FConnect, 'GET', PChar(FScript), 'HTTP/1.1', '', @Ansi, INTERNET_FLAG_RELOAD, 0);
  38.       if not Assigned(FConnect) then Exit;
  39.       try
  40.         if not (HttpAddRequestHeaders(FRequest, Header, Length(Header), HTTP_ADDREQ_FLAG_REPLACE or HTTP_ADDREQ_FLAG_ADD)) then Exit;
  41.         if not (HttpSendRequest(FRequest, nil, 0, nil, 0)) then Exit;
  42.         Len := sizeof(status);
  43.         Index := 0;
  44.         HttpQueryInfo(FRequest, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER, @Result.Status, Len, Index);
  45.         FillChar(Buff, SizeOf(Buff), 0);
  46.         repeat
  47.           Result.Payload := Result.Payload + Buff;
  48.           FillChar(Buff, SizeOf(Buff), 0);
  49.           InternetReadFile(FRequest, @Buff, SizeOf(Buff), BytesRead);
  50.         until BytesRead = 0;
  51.       finally
  52.         InternetCloseHandle(FRequest);
  53.       end;
  54.     finally
  55.       InternetCloseHandle(FConnect);
  56.     end;
  57.   finally
  58.     InternetCloseHandle(FSession);
  59.   end;
  60. end;


-----
xchg dword [eax], eax


| Сообщение посчитали полезным: Crawler

Ранг: 53.9 (постоянный), 33thx
Активность: 0.050
Статус: Участник

Создано: 28 мая 2014 19:08 · Поправил: deniskore
· Личное сообщение · #4

Если не принципиально используйте Wininet
Вот запрос погоды у яндекса.
Code:
  1. #include <windows.h>
  2. #include <WinInet.h>
  3. #include <iostream>
  4. #include <string>
  5. #include <fstream>
  6. #pragma comment(lib,"wininet.lib")
  7.  
  8. void GetWeather(void)
  9. {
  10.          HINTERNET hInternet = InternetOpenW(L"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  11.          wchar_t* hdrs = L"Content-Type: application/x-www-form-urlencoded";
  12.          DWORD dwFlags = INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE;
  13.          if (hInternet == NULL)
  14.          {
  15.                  std::cout << "InternetOpenW failed with error code " << GetLastError() << std::endl;
  16.          }
  17.          else
  18.          {
  19.                  HINTERNET hConnect = InternetConnectW(hInternet, L"export.yandex.ru", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL);
  20.  
  21.                  if (hConnect == NULL)
  22.                  {
  23.                         std::cout << "InternetConnectW failed with error code " << GetLastError() << std::endl;
  24.                  }
  25.                  else
  26.                  {
  27.                         const wchar_t* parrAcceptTypes[] = { L"text/*", NULL };
  28.                         HINTERNET hRequest = HttpOpenRequestW(hConnect, L"POST", L"/weather-ng/forecasts/27612.xml", NULL, NULL, parrAcceptTypes, dwFlags, 0);
  29.  
  30.                         if (hRequest == NULL)
  31.                         {
  32.                               std::cout << "HttpOpenRequestW failed with error code " << GetLastError() << std::endl;
  33.                         }
  34.                         else
  35.                         {
  36.                               BOOL bRequestSent = HttpSendRequestW(hRequest, hdrs, wcslen(hdrs), NULL, NULL);
  37.  
  38.                               if (!bRequestSent)
  39.                               {
  40.                                    std::cout << "HttpSendRequestW failed with error code " << GetLastError() << std::endl;
  41.                               }
  42.                               else
  43.                               {
  44.                                    std::string strResponse;
  45.                                    const int nBuffSize = 1024;
  46.                                    char buff[nBuffSize];
  47.  
  48.                                    BOOL bKeepReading = true;
  49.                                    DWORD dwBytesRead = -1;
  50.  
  51.                                    while (bKeepReading && dwBytesRead != 0)
  52.                                    {
  53.                                        bKeepReading = InternetReadFile(hRequest, buff, nBuffSize, &dwBytesRead);
  54.                                        strResponse.append(buff, dwBytesRead);
  55.                                    }
  56.  
  57.                                    std::ofstream myf("E:\weather.xml");
  58.                                    myf << strResponse;
  59.                                    myf.close();
  60.  
  61.                               }
  62.  
  63.                               InternetCloseHandle(hRequest);
  64.                         }
  65.  
  66.                         InternetCloseHandle(hConnect);
  67.                  }
  68.  
  69.                  InternetCloseHandle(hInternet);
  70.          }
  71.  
  72. }
  73.  
  74. int main(void)
  75. {
  76.          GetWeather();
  77. }


| Сообщение посчитали полезным: Crawler

Ранг: 46.8 (посетитель), 20thx
Активность: 0.040
Статус: Участник

Создано: 28 мая 2014 19:13
· Личное сообщение · #5

http://stackoverflow.com
"C++ requires a little more work then other languages. You will need to connect to Google's REST Search API(https://developers.google.com/web-search/docs/?csw=1#fonje) and then use a JSON parser to parse out the search results. Json.org (http://www.json.org/) has a collection of JSON parsers in various languages."



Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 28 мая 2014 19:51
· Личное сообщение · #6

преобразовать IWebBrowser2.document в IHTMLDocument* а из него уже достать innerhtml



Ранг: 590.6 (!), 408thx
Активность: 0.360.18
Статус: Модератор

Создано: 28 мая 2014 20:54
· Личное сообщение · #7

Veliant
В принципе можно любое двигло для рендеринга использовать, которое умеет динамику исполнять. С осликом тоже есть заморочки, если навигация нужна.

-----
старый пень




Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 28 мая 2014 21:25
· Личное сообщение · #8

Скачайте нормальный пример паука на базе хоть того же Poco, к чему эти костыли если не малварь пишите.



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 28 мая 2014 23:16
· Личное сообщение · #9

Veliant пишет:
IWebBrowser2.document

COM что ли? Фу какая погань!

Qt юзайте. Там есть WebKit, это то, что вам нужно. Сам недавно писал софт для дампа базы данных e-mail'ов и номеров телефонов.




Ранг: 216.9 (наставник), 85thx
Активность: 0.310.15
Статус: Участник
X-Literator

Создано: 29 мая 2014 10:17 · Поправил: Crawler
· Личное сообщение · #10

Не ожидал столько ответов! Всем благодарен за помощь, плюсану после лимита)

Не малварь, ищу специфические серваки. Если у кого-то будут ещё идеи, лишним не будет)


* Решил пока попользоваться вариантом INT (с QT уже имел дело, хотя и не так плотно). Но попробую все варианты - чисто ради интереса)


UPD2: всем большое спасибо еще раз! Ушел разбираться с QT - это, видимо, надолго. Кстати, вариант deniskore сработал, только поменял в заголовках content-type и еще парочку параметров. Ну, и тип запроса на GET. =)

-----
Харе курить веники и нюхать клей, к вам едет из Америки бог Шива, и он еврей.




Ранг: 5.7 (гость), 1thx
Активность: 0=0
Статус: Участник

Создано: 30 мая 2014 17:13
· Личное сообщение · #11

Crawler
просил без GUI
Я, например, использовал cURL - это по сути браузер для работы через командную строку.
Программа поддерживает протоколы: FTP, FTPS, HTTP, HTTPS, TFTP, SCP, SFTP, Telnet, DICT, File: , LDAP а также POP3, IMAP и SMTP. Также cURL поддерживает сертификаты HTTPS, методы HTTP POST, HTTP PUT, загрузку на FTP, загрузку через формы HTTP.
писал программу, которая генерила нужные мне команды работы с веб-серверами, т.к. cURL выводит результат в stdout я создавал пайп для перенаправления стандартного вывода и потом уже парсил результат, как хотел.
Если вывода относительно мало можно вывод перенаправлять в файл и работать с файлом, но это долго, если генеришь тысячу страниц...




Ранг: 110.8 (ветеран), 104thx
Активность: 0.090.01
Статус: Участник

Создано: 30 мая 2014 17:22
· Личное сообщение · #12

saffers пишет:
писал программу, которая генерила нужные мне команды работы с веб-серверами, т.к. cURL выводит результат в stdout я создавал пайп для перенаправления стандартного вывода и потом уже парсил результат, как хотел.


Вот это извраааат........ OLE не канает ?
Попробуй в таких случая воспользоваться --> Этим <--

Учим архитектуру


 eXeL@B —› Программирование —› C++ - получить код html-страницы
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати