Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.81/58: Рейтинг темы: голосов - 58, средняя оценка - 4.81
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
1

Веб-браузер, парсинг в общем работа с веб-страничками!

22.08.2012, 15:46. Показов 11184. Ответов 46
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здраствуйте! Вот тут решил попрактиковаться в работе с WebBrowser..

Постановка задачи:
Открыл я свой браузер открыл страницу: WebBrowser1->Navigate("URL");
Страница загрузилась. На ней есть кнопка которую по задумке мне потребуется нажать, эта кнопка открывает другую страницу, причем не в этой же вкладке, а в другой.

Проблема:
Эта страница открывается в Internet Explorer, надо в моем же приложении.

Вопрос:
Как организовать открытие подобных страниц в моем же приложении?! Что то читал про PageControl, но не понял как его связать.. как после нажатия кнопки создать в нем новую страницу и как сделать что бы в ней открылась та страница?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.08.2012, 15:46
Ответы с готовыми решениями:

веб браузер на borland c++
веб браузер на borland c++ как узнать размер открито сайта. Сколько килобайтов.

Какой веб браузер стоит по умолчанию
Сабж. Как узнать какой ВБ стоит по умолчанию?

Веб-браузер в черно-белых тонах
Стоит задача реализовать интерфейс(браузер) для дальтоников грубо говоря. Вопрос в тыл... Сам...

Веб-браузер, периодически открывающий страницы и выполняющий поиск по ключевым словам
Доброго времени суток. Вопрос такой: есть браузер на c++ builder и нужно сделать так, чтобы он с...

46
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
23.08.2012, 20:02  [ТС] 21
Author24 — интернет-сервис помощи студентам
http://vk.com/app2926589 Вот это приложение из контакта.. Посреди него большая надпись Мне нравится с сердцем вот на эту надпись я и пытаюсь нажать программно.. нажал уже на все что есть в контакте и не только в нем и на других сайтах по нажималось уже все.. а тут не получается
0
Почемучка)
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
23.08.2012, 20:48 22
Andersen1313, нужно было так сразу и сказать вы собиратель монет)
а если серьёзно есть другой способ и с builder он не связан. Покопайте в сторону ка мне кажется user js.B помниться мне была такая программа ты ей показываешь что нажимать и она сама нажимает)(что то вроде автокликера для web many)
На с++ builder -можно что то вроде этого ( указать кординаты мыши на кнопку мне нравится с сердцем) и программный клик на это место + таймер для повтора)
Но эта тема не закона)и скоро закроют твою тему наверно.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.08.2012, 20:50 23
Думаю вполне законна,так как автоклик не вмешивается в исходный код...
0
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
23.08.2012, 20:55  [ТС] 24
Собиратель монет??? что это значит? я просто взял для примера это приложение потому что именно оно меня сподвигло.. первая и единственная цель в поднятой теме это моё стребление изучить данную область

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

А насчет координат я уже наштамповал кучу программ.. и обои скачивать с сайта и во всех приложениях автоматом все тыкается.. но у всех у них есть одна проблема если друг время выставленнео мной в таймере на ожидание окажется малым для загрузки какой либо страницы, стабильность выполнения такого автокликера сходит на нет, приходится сидеть и контролировать чтобы все точно попадало куда надо
0
Почемучка)
1244 / 304 / 30
Регистрация: 23.12.2010
Сообщений: 2,001
Записей в блоге: 1
23.08.2012, 21:01 25
Цитата Сообщение от Andersen1313 Посмотреть сообщение
Собиратель монет??? что это значит?
Ну по скриншоту там видно что монеты за клики дают)
Andersen1313, мне кажется можно узнать степень загрузки страницы.
0
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
23.08.2012, 21:04  [ТС] 26
Вот это было бы хорошо)))
0
Практикантроп
4826 / 2718 / 526
Регистрация: 23.09.2011
Сообщений: 5,777
23.08.2012, 21:12 27
- это клик на картинке; вот это место__
HTML5
1
2
3
4
5
6
7
    <div id="apps_i_slider">
      <div style="width: 607px;">
        <div class="apps_i_sl fl_l"><img src="http://cs402424.userapi.com/v402424257/2aa2/8nqvpudTAd4.jpg" class="apps_i_sl_img" /></div>
      </div>
    </div>
 
  </div>
0
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
23.08.2012, 21:29  [ТС] 28
Цитата Сообщение от nick42 Посмотреть сообщение
- это клик на картинке; вот это место__
HTML5
1
2
3
4
5
6
7
    <div id="apps_i_slider">
      <div style="width: 607px;">
        <div class="apps_i_sl fl_l"><img src="http://cs402424.userapi.com/v402424257/2aa2/8nqvpudTAd4.jpg" class="apps_i_sl_img" /></div>
      </div>
    </div>
 
  </div>
извините я не понял от куда это?
0
Практикантроп
4826 / 2718 / 526
Регистрация: 23.09.2011
Сообщений: 5,777
23.08.2012, 21:51 29
- да я опоздал; пока писал - несколько отзывов добавилось. А фрагмент взят со странички-оригинала... искать нужно не ид кнопки, так как это всё одна картинка и ид у нее - <id="apps_i_slider">.__
Миниатюры
Веб-браузер, парсинг в общем работа с веб-страничками!  
0
Практикантроп
4826 / 2718 / 526
Регистрация: 23.09.2011
Сообщений: 5,777
23.08.2012, 21:56 30
А вообще - я помолчу лучше. У меня слишком мало опыта в ВЭБ (дизайне и т.д.)
0
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
24.08.2012, 09:59  [ТС] 31
nick42, у меня возникла идея.. попробую её реализовать, может быть вы знаете, может надо сначала извлечь код фрейма как в переменную типа WebBrowser, а потом уже проделать все тоже с ней? Как можно извлечь отдельно код фрейма?

Добавлено через 3 часа 0 минут
Вот к чему я пришел в моих попытках вытащить код фрейма:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    if( WebBrowser1->Document )
    {
        String iFrame="fXDc8f6d";
        TComInterface<IHTMLDocument2> pDocument;
        WebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&pDocument);
        if( pDocument )
        {
            TComInterface<IHTMLFramesCollection2> pCollection; //набор фреймов
            pDocument->get_frames(&pCollection); //получаю все фреймы на странице
            if( pCollection )
            {
                long *CountFrame;
                CountFrame = new (long); 
                pCollection->get_length(CountFrame); //Узнаю кол-во найденных фреймов
Я получил набор фреймов, проберил через браузер кол-во найденных в приложение фреймов совпадает с действительно существующими на страницы значит все должно быть правильно.
Вот вопрос как из переменной pCollection вытащить отдельный фрейм?

Вроде бы при помощи метода item, но я не понял как его использовать...
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
24.08.2012, 10:29 32
Цитата Сообщение от Andersen1313 Посмотреть сообщение
как из переменной pCollection вытащить отдельный фрейм?
Вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
          IHTMLFramesCollection2 *pFrames = NULL;
          long frameCount = 0;
 
          if(SUCCEEDED(pHTMLDocument->get_frames(&pFrames))) // Вот коллекция фреймов.
          {
             pFrames->get_length(&frameCount);
             VARIANT vFrame;
             VARIANT ret;
             vFrame.vt = VT_UINT;
 
             // У меня здесь делается перебор всех фреймов, измени как тебе нужно
             for(long frameIx = 0; frameIx < frameCount; frameIx++)
 
             {
                vFrame.lVal = frameIx;
                if(SUCCEEDED(pFrames->item(&vFrame, &ret)))
                {
                   IHTMLWindow2 *pWindow = NULL;
                   if(SUCCEEDED(ret.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&pWindow)))
                   {
                      IHTMLDocument2 *pDoc = NULL;
                      if(SUCCEEDED(pWindow->get_document(&pDoc)))
                      {
                         getLinksFromDoc(pDoc); // Это был кусок программы для вытаскивания линков со всей страницы
                      }
                   }
                }
             }
          }
1
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
24.08.2012, 10:52  [ТС] 33
Вот тут вы задаете номер фрейма?
C++
1
vFrame.lVal = frameIx;
А как бы мне при переборке найти нужный фрейм по ID?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
24.08.2012, 11:37 34
проверил вот такой вариант:
C++
1
2
vFrame.vt = VT_BSTR;
vFrame.bstrVal = L"myOwnID";
на фрейме, заданном:
HTML5
1
<iframe id="myOwnID" src="index.htm" ... >
, все нормально, находит.
1
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
24.08.2012, 14:50  [ТС] 35
Цитата Сообщение от UI Посмотреть сообщение
проверил вот такой вариант:
Код C++
1
2
vFrame.vt = VT_BSTR;
vFrame.bstrVal = L"myOwnID";
на фрейме, заданном:
Код HTML
1
<iframe id="myOwnID" src="index.htm" ... >
, все нормально, находит.
Это уже не в цикле можно делать? просто одним выражением задать нужный ID и он найдется сразу?

Добавлено через 5 минут
Блин.. имя фрейма постоянно меняется... если оно меняется фрейм ни как нельзя вытащить? например если известно в какой div располагается.. или порядок известен они же все время в приложении у меня будут под постоянными номерами появляться если страничка одна и та же?

Добавлено через 7 минут
Еще вопрос существует возможность искать елементы по комбинации классов или еще каким нибудь атрибутам? бывает что у тэга нет атрибута name или ID

Добавлено через 18 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
if( WebBrowser1->Document )
    {
        TComInterface<IHTMLDocument2> pDocument;
        WebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&pDocument); //Получаю весь документ
        if( pDocument )
        {
            TComInterface<IHTMLFramesCollection2> pFrames;                              //Получаю фреймы со страницы
            pDocument->get_frames(&pFrames);
            if( pFrames )                                                               //если фреймы есть
            {
                long CountFrame;
                pFrames->get_length(&CountFrame);
                VARIANT vFrame;
                vFrame.vt = VT_UINT;
                VARIANT ret;
                for(long frameIx = 0; frameIx < CountFrame; frameIx++)
                {
                    vFrame.lVal = frameIx;                                              //Заношу номер фрейма
                    if(SUCCEEDED(pFrames->item(&vFrame, &ret)))
                    {
                        TComInterface<IHTMLWindow2> *pWindow = NULL;
                        if(SUCCEEDED(ret.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&pWindow))) //Если фрейм найден
                        {
                            TComInterface<IHTMLElementCollection> pCollection;
                            pDocument->get_all(&pCollection);                                   //Получаю набор всех елементов в фрейме
                            if( pCollection )                                                   //если элементы есть
                            {
                                TComInterface<IDispatch> pDisp;
                                pCollection->item(TVariant(WideString("like")), TVariant(0), &pDisp); //Получаю елемент с ID или name "like"
                                if( pDisp )
                                {
                                    TComInterface<IHTMLElement> pElement;
                                    pDisp->QueryInterface(IID_IHTMLElement, (LPVOID*)&pElement);
                                    if( pElement )                                                //Если элемент есть то счелкаю его
                                    {
                                        pElement->click();
                                    }
                                }
                            }
                        }
                    }
                }
Вот эта строчка ни разу не нашла элемент с id="like":
C++
1
pCollection->item(TVariant(WideString("like")), TVariant(0), &pDisp); //Получаю елемент с ID или name "like"
Вот отрезок анализируемого кода:
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div id="app_2926589_container" class="app_container loaded" style="width: 827px; height: 1000px;">
 
<iframe name="fXD183ca" webkitallowfullscreen="true" mozallowfullscreen="true" allowfullscreen="true" frameborder="0" src="http://like2.holycow.ru/index.html?api_url=http://api.vk.com/api.php&amp;api_id=2926589&amp;api_settings=8470&amp;viewer_id=21307813&amp;viewer_type=0&amp;sid=b21908f378daf7f50d96f74104a4ffcdac5f717d4b8a4dd575d3bf54c53f22&amp;secret=9185a85cf9&amp;access_token=73e1e160229c681b72fbaafab572886738772a472a4e1d365dbd20fb50bd386&amp;user_id=0&amp;group_id=0&amp;is_app_user=1&amp;auth_key=9c8be11cd10fb03c749ef2eb9c43dd1f&amp;language=0&amp;parent_language=0&amp;ad_info=ElsdCQNdQlVjDQVYAwJSXHt5AkQ8HTJXUVBBJRVBNwoIFjI2HA8E&amp;api_result=%7B%22response%22%3A%5B%7B%22uid%22%3A21307813%2C%22first_name%22%3A%22%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%22%2C%22last_name%22%3A%22%D0%9B%D0%BE%D0%BF%D0%B0%D1%82%D0%B8%D0%BD%22%2C%22sex%22%3A2%7D%5D%7D&amp;referrer=unknown&amp;lc_name=6f4d105a&amp;hash=" width="100%" scrolling="no" height="1000px">
<!DOCTYPE html>
<html>
    <head>
  ...
    </head>
    <body >
    ###Тут куча блоков и скриптов###
 
    
<div class="buttons">
        <div id="timer"><strong>48 секунд</strong>, чтобы<br>поставить лайк.</div>
        <a id="like" href="Какой то URL" target="_blank" style="visibility: visible; ">Мне нравится</a> [COLOR="red"]<--- Вот это нужная мне ссылка(она внутри фрейма)[/COLOR]
        <a id="refresh" href="#" style="">Пропустить</a>
        <a id="refreshReady" href="#" style="display: none; ">Обновить</a>
      </div>
 
      ###Тут куча блоков и скриптов###
    </body>
</html>
</iframe>
</div>
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
24.08.2012, 15:16 36
У тебя что, фрейм с другого домена? Тогда надо делать по-другому. Я уже приводил на одном из форумов реализацию на Дельфи, сможешь перенести на Билдер?

Вот код на Дельфи
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
procedure TForm1.Button1Click(Sender: TObject);
 
   // Эта функция была найдена на просторах Интернета
   // Один из авторов - Rik Barker
   function CrossDomainFrame(Doc : IHTMLDocument2;
                             nFrame : Integer) : IWebBrowser2;
   var
      theContainer : IOLEContainer;
      Enumerator : IEnumUnknown;
      nFetched : PLongInt;
      unknownFrame : IUnknown;
   begin
      Result := nil;
      nFetched := nil;
      theContainer := Doc as IOleContainer;
      theContainer.EnumObjects(OLECONTF_EMBEDDINGS, Enumerator);
      Enumerator.skip(nFrame);
      Enumerator.next(1, unknownFrame, nFetched);
      unknownframe.QueryInterface(IID_IWebBrowser2, Result);
   end;
 
var
   Doc : IHTMLDocument2;
   Frames : IHTMLFramesCollection2;
   i, j : Integer;
   iCurr, iLink : OleVariant;
   Disp : IDispatch;
   Frame : IHTMLWindow2;
   Lnk : IHTMLElementCollection;
   CurrLnk : IHTMLElement;
begin
   Doc := WebBrowser1.Document as IHTMLDocument2;
   Frames := Doc.frames;
   for i := 0 to Frames.length - 1 do
   begin
      iCurr := i;
      Disp := Frames.item(iCurr);
      OleCheck(Disp.QueryInterface(IID_IHTMLWindow2, Frame));
 
      // Для надежности работаем со всеми фреймами, как с междоменными:
      Doc := CrossDomainFrame(WebBrowser1.Document as iHTMLDocument2,
                              iCurr).document as iHTMLDocument2;
 
      // Теперь возьмем линки, присутствующие на текущем фрейме
      Lnk := Doc.links;
      for j := 0 to Lnk.length - 1 do
      begin
         iLink := j;
         CurrLnk := Lnk.item(varEmpty, iLink) as IHTMLElement;
         // на 5-ом фрейме (на рабочей странице это блок Гуглорекламы)
         // жмем первую ссылку:
         if (i = 4) and (j = 0) then
         begin
            CurrLnk.click;
            Exit; // Всё, выходим из перебора
         end;
      end;
   end;
 
end;
1
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
24.08.2012, 16:07  [ТС] 37
Хорошо щас разберусь! Вопрос: то что я сделал выше если фрейм будет с того же домена, то этот бы код работал и нашел бы нужную ссылку по ID???

Добавлено через 11 минут
Как я понял все идет как и у меня вот до этого момента:
Delphi
1
2
3
// Для надежности работаем со всеми фреймами, как с междоменными:
      Doc := CrossDomainFrame(WebBrowser1.Document as iHTMLDocument2,
                              iCurr).document as iHTMLDocument2;
Потом эта функция производит преобразования, и уже после них идет работа с фреймом. Да?! функцию щас разберу..
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
24.08.2012, 16:11 38
Цитата Сообщение от Andersen1313 Посмотреть сообщение
то что я сделал выше если фрейм будет с того же домена, то этот бы код работал и нашел бы нужную ссылку по ID???
Нет. Между 24 и 25 строкой ты пропустил этап получения IHTMLDocument2 из pWindow, из которого потом надо получить IHTMLElementCollection. Если добавишь - то будет работать и найдет ссылку по ID. Проверил только что.
1
8 / 8 / 1
Регистрация: 18.10.2010
Сообщений: 120
24.08.2012, 16:27  [ТС] 39
Может быть поэтому у меня и не работает? или все равно надо как на делфи вы привели код?

Добавлено через 45 секунд
Потому что я потом получал опять из pDocument который относится ко всей странице на которой как раз и нет нужной мне ссылки

Добавлено через 3 минуты
Чет я не понимаю как мне получить IHTMLDocument2 из pWindow..

Ранее я получал IHTMLDocument2 вот так
C++
1
2
TComInterface<IHTMLDocument2> pDocument
WebBrowser1->Document->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&pDocument);
Но в этом случае как я понимаю это не работает, потому что у pWindow нет свойства Document
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,432
Записей в блоге: 8
24.08.2012, 16:29 40
Цитата Сообщение от Andersen1313 Посмотреть сообщение
Потому что я потом получал опять из pDocument который относится ко всей странице
Если ты сделаешь так:

C++
1
2
3
4
5
6
7
8
if(SUCCEEDED(pFrames->item(&vFrame, &ret)))
{
    IHTMLWindow2 *pWindow = NULL;
    if(SUCCEEDED(ret.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&pWindow)))
    {
        IHTMLDocument2 *pDoc = NULL;
        if(SUCCEEDED(pWindow->get_document(&pDoc)))
        {
, то pDoc будет именно фреймовый, а не всего документа.
Цитата Сообщение от Andersen1313 Посмотреть сообщение
или все равно надо как на делфи вы привели код?
Если фрейм междоменный - то надо делать по Дельфийскому варианту.
1
24.08.2012, 16:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.08.2012, 16:29
Помогаю со студенческими работами здесь

Работа с веб камерой
Здрасьте. Пробую захват изображения с вебкамеры(Genius iLook 300). нарыл такой код: HWND...

Работа с веб-камерой, видеосвязь
доброго времени суток! передо мной стоит задача организовать общение по веб-камере между двумя...

Работа с данными веб страниц
Здраствуйте. Подскажите новичку! Как мне пропарсить какую нибудь веб страницу, получить с нее...

Одновременная работа с двумя одинаковыми веб-камерами
Здраствуйте! Начинаю разрабатывать приложение. Приложению необходимо одновременно работать с двумя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru