Chromium

вторник, 26 августа 2014 г., 9:25:29, написал admin

Chromium – это компонент браузера для Delphi, основанный на движке Chrome. Собственно, в этом и есть его главное преимущество перед стандартным WebBrowser (который основывается на IE). Другое преимущество Chromium – это удобная работа с куками, что незаменимо при работе с социальными сетями. Может, и WebBrowser тоже такое умеет, но даже не стал глубоко копать – т.к. IE – это абсолютное зло)

В этой статье речь пойдет о Chromium под Delphi 7. В принципе теоретически он наверное встанет и под Lazarus, особенно старая версия: https://code.google.com/p/delphichromiumembedded/

Установка

Идем за самой свежей версией: https://code.google.com/p/dcef3/

Качаем себе на комп, распаковываем сюда: c:\Program Files (x86)\Borland\Delphi7\Lib\dcef3\

Копируем все файлы исходников из c:\Program Files (x86)\Borland\Delphi7\Lib\dcef3\src в c:\Program Files (x86)\Borland\Delphi7\Lib

Открываем через Delphi 7 пакет  c:\Program Files (x86)\Borland\Delphi7\Lib\dcef3\packages\DCEF_D7.dpk

Делаем компиляцию, инсталлируем.

Теперь в конце списка вкладок должна появиться новая вкладка  Chromium.

Закрываем пакет, изменения не сохраняем, перезапускаем Delphi.

Работа с компонентом

Куки

Создадим новый проект, назовем его допустим DelphiBrowser.

Давайте попробуем загрузить страничку ВК.

На форме размещаем компонент TChromium  и кнопку TBitBtn, вешаем событие на кнопку

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  CookieManager: ICefCookieManager;
  CookiesPath : String;
begin
  CookiesPath := ExtractFilePath(Application.ExeName) + ' Cookies/User1';
  CookieManager := TCefCookieManagerRef.Global;
  CookieManager.SetStoragePath(CookiesPath, TRUE );
  Chromium1.Load('http://vk.com/');
end;

В uses проверяем, чтобы был подключен модуль ceflib

В папку с проектом метаем содержимое из c:\Program Files (x86)\Borland\Delphi7\Lib\dcef3\bin\Win32\

Создаем папку Cookies, в ней подпапку User1. Здесь будут лежать куки первого пользователя. Можно создать папку User2 и т.д. и потом переключаться между ними.

Сохраняем изменения и запускаем прогу.

Если все сделано правильно, то при клике на кнопку загрузиться ВК. Войдите под своим логином на сайт, закройте программу. Запустите её снова, нажмите на кнопку. Вы должны оказаться под своим логином, т.е. куки сработали.

Адресная строка

Давайте теперь добавим «адресную строку». Возьмите компонент TLabeledEdit, в заголовок вбейте «Адрес». Поместите вторую кнопку TBitBtn, и повесьте не неё такой обработчик:

procedure TForm1.BitBtn2Click (Sender: TObject);
begin
  Chromium1.Load(LabeledEdit1.Text);
end;

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

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

Выделяем Chromium1 на форме, жмем F11 (вызов Инспектора), переходим на вкладку Events и дважды кликаем на OnAddressChange. Добавляем код

procedure TForm1.Chromium1AddressChange(Sender: TObject;
  const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
begin
  LabeledEdit1.Text:=url;
end;

Все, теперь при переходе на другую страницу из браузера её адрес отобразиться в поле.

Скрипты

Теперь рассмотрим как подгружать код JavaScript.

Добавим третью кнопку и прицепим к ней такой обработчик:

procedure TForm1.BitBtn3Click(Sender: TObject);
var
  code: ustring; 
begin
if (Chromium1.Browser.GetMainFrame<>nil) then
  begin
  code:='alert("Hello!");';
  Chromium1.Browser.GetMainFrame.ExecuteJavaScript(code,'',0);
  end
  else ShowMessage('FatalError');
end; 

GetMainFrame проверяет, загружена ли страница. GetMainFrame.ExecuteJavaScript выполняет код JS, в данном случае выводит "Hello!". Но понятно что через JS мы можем манипулировать деревом DOM, совершать различные действия (вбивать в поля данные, кликать по кнопкам, получать значения).

Консоль

Давайте теперь зацепим консоль.

Добавим на форму компонент TMemo.

Повесим обработчик в Chromium на OnConsoleMessage, напишем там такой код:

procedure TForm1.Chromium1ConsoleMessage(Sender: TObject;
  const browser: ICefBrowser; const message, source: ustring;
  line: Integer; out Result: Boolean);
begin
  Memo1.Lines.Add(message);
end;

Исходный код страницы

Давайте получим весь html код страницы.

Добавим на форму еще один компонент TMemo.

Повесим обработчик в Chromium на OnLoadEnd, напишем там такой код:

procedure TForm1.Chromium1LoadEnd(Sender: TObject;
  const browser: ICefBrowser; const frame: ICefFrame;
  httpStatusCode: Integer);
begin
 if (frame <> nil) and frame.IsMain  then
 begin
    Memo1.Lines.Add('Загрузка страницы завершена!'); // для вывода в консоль
    frame.GetSourceProc(callback);
  end;
end;

procedure callback(const str: ustring);
begin
  Form1.Memo2.Lines.Clear; // очищаем Memo
  Form1.Memo2.Lines.Add(str);
  Form1.Memo2.Lines.Add('------------end-frame--------------');
  Application.ProcessMessages;
end;

Блокируем ресурсы

Допустим мы не хотим видет какую-то рекламу. Как заблокировать загрузку ресурса по адресу? Очень просто:

Повесим обработчик в Chromium на OnBeforeResourceLoad, напишем там такой код:

procedure TForm1.Chromium1BeforeResourceLoad(Sender: TObject;
  const browser: ICefBrowser; const frame: ICefFrame;
  const request: ICefRequest; out Result: Boolean);
var
  url: String;
  pos: Integer;
begin
  Result := False; //по умолчанию разрешаем загрузку ресурса (страницы, изображения, видео...)
  url:=request.GetUrl; //получаем текущий урл
  pos:=PosEx('youtube.com', url); //ищем вхождение слова "youtube.com" в урл
  if pos>0 then //если слово содержиться, то
  begin
    Result := True; //запрещаем его загрузку. Таким образом я избавился от лишнего мусора...
  end;  
end;

Настройка прокси

Обнаружилась одна неприятная особенность: своего прокси у Chromium нет. Вообще нет и похоже не предвидеться. Глянул браузеры Google Chrome и Opera - все они используют настройки прокси от системы (т.е. IE). Только Mozilla Firefox продолжает использовать собственные настройки. После долгих часов поиска понял, что похоже единственное решение - подмена каким-то образом системных настроек. Но как конкретно это сделать - не нашел, встречал только упоминания. Буду благодарен, если в комментариях оставите ссылки. Ну а сейчас единственный рабочий вариант - это прописывать параметры прокси в командной строке:

  test.exe --proxy-server=255.255.0.1:80

Соотвественно чтобы программно менять прокси - нужно создать две программы - одна вызывает другую с нужными параметрами...

В параметрах командной строки также можно сменить user-agent:

  test.exe --user-agent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en)"

Еще исследуются…

Собственно, на этом и закончились мои успехи. Непонятно, как получать данные из DOM? Чтобы они были доступны не только скрипту, но и самой проге. Конечно, получив исходный код страницы можно распарсить его, но во-первых, это не универсальное решение, а во-вторых - динамически подгружаемый контент по-прежнему остается недоступным... Как получить всю DOM модель документа в любой момент времени с помощью самого компонента – увы, не разобрался. Т.е. пока что реальная польза от программы – это заполнение полей своими данными, а до полноценного парсера она не дотягивает….  

 

Тэги: Chromium Delphi Категория: Delphi
 

Комментарии к статье

  • 2016-06-10 Константин Винниченко

    Там не глюк, что-то с JS скриптами. Вылетают не все сайты, а на некоторых. Чтобы не вылетало, посмотрите как демки сделали, там есть заплатка.

  • 2016-05-12 DelphiCromium

    PS. Версия хромиума на данный момент последняя - 39 с че мто

  • 2016-05-12 DelphiCromium

    вылетает программа на большинстве сайтов просто при серфе. Может такая
    версия хромиума глючная? Я на ХР. Пробовал Д7 и Д2010, на обоих так.

  • 2016-02-23 Vladislav Novikov

    пацаны помогите не могу комплиировать программу все сделал как показано у меня ошибка в uses я добавил туда ceflib все равно там же ошибка.пацаны мне оч нужно сделать это приложение помогите вот я в контакте пишите http://vk.com/id135471187 или на гугле krutoystalker@gmail.com или ответьте тут

  • 2015-06-28 dmitxe

    Наверное можно... И я даже пытался - но не смог заставить заработать( Не видит... Если сумеете - поделитесь с нами)

  • 2015-06-28 dmitxe

    возможно версия обновилась, и что-то поменялось... я давно не обновлял компонент. Аналогичная ошибка была когда скопировал код от одной версии, а библиотеки были от другой... Долго не мог понять, в чем дело. Код и все dll должны быть от одной версии

  • 2015-06-28 dmitxe

    Если реклама идет с другого домена (не с ютуба) - то да, можно... Но для этого нужно знать домен, с которого идет реклама

  • 2015-06-28 Алексей

    Есть такой вапрос, можно ли добовлять как нибуть свои расширения, как у Google Chrome

  • 2015-05-17 Сергей

    Пытался повторить((( ругается на ---frame.GetSourceProc(callback);

  • 2015-04-07 Дмитрий

    Здравствуйте! Отличная статья! Спасибо!
    Подскажите пожалуйста, как блокировать видео-рекламу, которая например появляеться перед просмотром видео на ютубе?
    Заранее благодарю!