Jak odczytać kod HTML strony otwartej w Firefox'ie?

0

Witam,
tak jak w temacie.... Mam program w Delphi ktorym potrzebuje odczytac zawartosc (kod HTML) strony otwartej w Firefox'ie.
Zaznacze ze opcja z pobraniem adresu strony i wczytaniu w TWebBrowser nie wchodzi w gre.. Musze bezposrednio odczytac z Uchwytu do okna Firefox...
Ale jak?
Jakis pomysl?

Pozdrawiam

2

Myślę, że można napisać wtyczkę do Firefoxa, która w jakiś sposób będzie się komunikować z Twoim programem i to ta wtyczka będzie podawać kod strony.

Próby odczytu bezpośrednio z programu Firefox mogą się skończyć tym, że wyjdzie nowsza wersja Firefoxa i Twój program przestanie działać.

0

Bez przesady to chyba można zrobić za pomocą Microsoft UI Automation ale osobiście w Delphi się tym nie bawiłem. Może w Google jak dobrze poszukasz znajdziesz coś więcej na ten temat (dotyczącego Delphi bo C# jest aż za dużo).

1

A nie lepiej żeby program sam sobie pobierał kod html strony bez pośrednictwa firefoxa?

0

Nie... program ma byc rodzajem rozszerzenia do przegladarki internetowej. Uzytkownik musi pracowac pod Firefoxem. Tam jest uruchamiana aplikacja internetowa a program ma dodatkowo analizowac wyswietlane dane.
Czy ktos ma doswaidczenie z UI Automation pod Delphi?

3

Jeżeli w Firefoxie miałbyś otwarte okno, w którym widoczny będzie kod strony (któraś z opcji programistycznych) to możesz spróbować dobrać się do tego konkretnego okna. Ja coś podobnego ostatnio potrzebowałem i zrobiłem to tak:

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI, TlHelp32, ExtCtrls
function GetProcesID(exeName:String): Cardinal;
var
  Uchwyt:tHandle;
  Proces:tProcessEntry32;
begin
  Result := 0;
  Uchwyt:=CreateToolHelp32SnapShot(TH32CS_SNAPALL,0);
  Proces.dwSize:=SizeOf(Proces);
  if Integer(Process32First(Uchwyt,Proces))<>0 then
  repeat
    if (LowerCase(Proces.szExeFile) = LowerCase(exeName)) then
    begin
      Result := Proces.th32ProcessID;
      Break;
    end;
  until Integer(Process32Next(Uchwyt,Proces))=0;
  closehandle(Uchwyt);
end;

function GetHWndByPID(const hPID: THandle): THandle;
    type
    PEnumInfo = ^TEnumInfo;
    TEnumInfo = record
    ProcessID: DWORD;
    HWND: THandle;
  end;
    function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
    var
        PID: DWORD;
    begin
        GetWindowThreadProcessID(Wnd, @PID);
        Result := (PID <> EI.ProcessID) or
                (not IsWindowVisible(WND)) or
                (not IsWindowEnabled(WND));

        if not Result then EI.HWND := WND; //break on return FALSE
    end;
    function FindMainWindow(PID: DWORD): DWORD;
    var
        EI: TEnumInfo;
    begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
    end;
begin
    if hPID<>0 then
        Result:=FindMainWindow(hPID)
    else
        Result:=0;
end;

function EnumChildren(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
const
  TextBoxClass = 'Favorite directories (F2)';
var
  ClassName: array[0..259] of Char;
begin
  Result := True;
  GetClassName(hwnd, ClassName, Length(ClassName));
  Windows.GetWindowText(hwnd,classname,length(ClassName));
  if ClassName = TextBoxClass then
    TStrings(lParam).Add('Hurra');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  h: THandle;
begin
  h := GetHWndByPID(GetProcesID('DicomWorks.exe'));
  Memo1.Lines.Clear;
  EnumChildWindows(h, @EnumChildren, UINT_PTR(Memo1.Lines)); //tutaj odpalamy funkcję przeszukującą wszystkie childy parenta czyli w twoim wypadku Firefox.exe
  if Memo1.Lines[0] = 'Hurra' then //z tym memo to demo jest więc zastosuj sobie lepsze rozwiązanie
  begin
    //tutaj twój kod
  end;
end;
0

Dzieki jeczez raz... ale do tego momentu juz doszedlem... mam uchwyt do okna... ale jak odczytac zawartosc HTML w tym oknie?

0

Nie wiem czy się dobrze rozumiemy. To:

h := GetHWndByPID(GetProcesID('Firefox.exe'));

Zwraca uchwyt okna głównego

EnumChildWindows(h, @EnumChildren, UINT_PTR(Memo1.Lines));

odpala funkcję

function EnumChildren(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;

jest to wywołanie z Windows API i powoduje, że dla danego HWND wyszukiwane są wszystkie childy czyli labele edity itd w procesie firefox.exe
Ta konstrukcja:

GetClassName(hwnd, ClassName, Length(ClassName));
Windows.GetWindowText(hwnd,classname,length(ClassName));
if pos('<html',lowercase(ClassName)) > 0 then
//twoj kod

powoduje, że sprawdzane są wszystkie childy procesu firefox.exe i jeśli który będzie posiadał <html to masz sukces i możesz dalej sobie z tym coś robić ;)

0

Witam,
Mam ten sam problem co autor wątku.
Mam uchwyt okna firefox'a lecz potrzebuję adres strony.
Niestety GetClassName, GetWindowText i EnumChildren dają mi tylko tytuł okna.
Jeśli zapiszę stronę na dysku, to potrzebne mi dane dane są zapisane jako tekst (pewne współczynniki i adresy obrazów). Potrzebuję wygrzebywać te dane w tle przechodząc poprzez kolejne strony. Tytuł strony zawsze jest ten sam więc za pomocą FindWindow uzyskuję uchwyt okna. Potrzebuję odczytać adres strony lub jeśli to możliwe bezpośrednio jej zawartość.
Czy ktoś z Was robił coś podobnego lub umie to zrobić? Proszę o pomoc.
Pozdrawiam.

0

Nie jestem pewien ale czy dobranie się do przeglądarki jest na pewno możliwe z programu zewnętrznego? Chyba właśnie na tym polega działanie piaskownicy żeby właśnie nie można było wpływać za bardzo na przeglądarkę internetową? Wg mnie odczytacie nazwę karty i to wszystko.

Mogę się jednak mylić i na pewno nie obrażę się na sprostowanie mojej wypowiedzi.

Według mnie jedyne rozwiązanie to rozszerzenie do Firefoxa które będzie przekazywać kod html jak zasugerował @andrzejlisek

0
arturfir napisał(a):

Nie... program ma byc rodzajem rozszerzenia do przegladarki internetowej. Uzytkownik musi pracowac pod Firefoxem. Tam jest uruchamiana aplikacja internetowa a program ma dodatkowo analizowac wyswietlane dane.

A co to rozszerzenie ma robić?

0

Jak już pisałem podane tutaj przykłady nie działają. EnumChildren nic nie podaje, GetWindowText zwraca jedynie tytuł okna, GetClassName podaje mi klasę przeglądarki. Szukałem w WinAPI, ale bez skutku.

Próbowałem komunikacji przez TDDEClientConv. Spotkałem się z dziwnym działaniem:

  1. gdy nie ma otwartego okna przeglądarki nie wywołuje mi błędu/wyjątku
  2. jeśli jest otwarta przeglądarka, lecz tytuł strony inny niż żądany, j.w.
  3. jeśli znajdzie okno z żądanym tytułem strony, to niezależnie jaki podam RequestData, zwaca mi pusty ciąg, a w tle uruchamia kolejny mój program

Czy system nie ma dostępu do zawartości otwartych stron? Myślę że jeśli system ma dostęp do tych danych to przez WinAPI też powinno się dać. Zgadza się czy się mylę?

0

Nie znam się na meritum problemu i nie wiem, czy to ci coś pomoże, ale może pobaw się Inspektorem DOM do FF:
https://en.wikipedia.org/wiki/DOM_Inspector
https://developer.mozilla.org/pl/docs/Inspektor_DOM

Można w nim zobaczyć drzewo obiektów, tak samej przeglądarki jak i strony internetowej, która stanowi tu jedną z podgałęzi całości. I jak już zobaczysz, co w czym siedzi i jakie ma identyfikatory, to może wystarczy zbudować odpowiednie odwołanie do właściwego elementu?

0

Z TDDEClientConv znalazłem błąd, pomieszane uchwyty okien.
Niestety używając TDDEClientConv też nie uzyskałem danych z FireFox.
Próbowałem też GetActiveOLEObject, ale stale mam błąd "Nieprawidłowy ciąg klasy" pomimo że pobierałem przez GetClassName.

Próbowałem z Chrome, te same wyniki. WWW_GetWindowInfo zwraca puste ciągi.

0

Powiem tak, kiedys tez probowalem ten efekt osiagnac i chyba sie poddalem! Po prostu dalem sobie spokoj, nie udalo mi sie osiagnac tego celu

Gdzies na 4programmers jest aplikacja o nazwie Handler. Wlasciwie nawiazuje troche do w.w odpowiedzi, ale moznaby sie sprobowac nia pobawic.

Jeszcze mi przychodzi do glowy(spsob poboczny) wsylac do firefox.exe klawisze(za pomoca np Handler.exe) skrot klawiszowy Ctrl+S i zapisac strone np jako c:\test.html.

Tyle moge doradzic, gotowca nie udostepniam, ale mam nadzieje iz jakos pomoglem

1 użytkowników online, w tym zalogowanych: 0, gości: 1