Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.

how can i get source from an iframe?

Post Reply
User avatar
salvadordf
Posts: 4042
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: how can i get source from an iframe?

Post by salvadordf »

Hi,

Call TChromium.GetFrameNames to get all the frame names. Create a TStringList variable and cast it to TStrings to use it as the "aFrameNames" parameter.

Then call TChromium.RetrieveHTML with one of the frame names and use the TChromium.OnTextResultAvailable event to get the HTML source in the "aText" parameter.
User avatar
salvadordf
Posts: 4042
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: how can i get source from an iframe?

Post by salvadordf »

I have to confirm this but there seems to be an issue in Chromium or CEF when you use the "--site-per-process" switch, which is used by default in CEF4Delphi.

The function to get the frame names returns names from a previous web page when that switch is used. The old frame with that name is still in memory but it doesn't return the HTML source.

To avoid this issue, try setting GlobalCEFApp.SitePerProcess to FALSE before the GlobalCEFApp.StartMainProcess call in the DPR file.
User avatar
salvadordf
Posts: 4042
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: how can i get source from an iframe?

Post by salvadordf »

I just added a comment in a related CEF3 issue :
https://bitbucket.org/chromiumembedded/ ... er-process

I can only suggest that you set GlobalCEFApp.SitePerProcess to FALSE while this issue is fixed in the CEF3 project.
User avatar
salvadordf
Posts: 4042
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: how can i get source from an iframe?

Post by salvadordf »

Hi,

Chromium uses multiple processes and threads for different tasks. Sometimes you need to execute a function or to get some data from another process and this architecture forces you to use "visitors" with asynchronous functions.

The TChromium.RetrieveHTML and TChromium.RetrieveText functions are a clear example of this because they get data from the DOM, which is in a different process.

You can't accelerate the asynchronous functions. You can only adapt your code to handle asynchronous results.

In this case, you can :
  • Call the next RetrieveHTML only after you have read the previous result.
  • Add each result to a TStringList.
User avatar
salvadordf
Posts: 4042
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: how can i get source from an iframe?

Post by salvadordf »

You can use the code in the MiniBrowser demo and customize the Chromium1TextResultAvailable procedure.

Replace the code that assigns the aText to the clipboard with your own code. Then call RetrieveHTML inside the Chromium1TextResultAvailable procedure with the next frame name or ID if there's any frame left.

Code: Select all

procedure TMiniBrowserFrm.Chromium1TextResultAvailable(Sender: TObject; const aText: ustring);
begin
  MyCustomHTMLHandlingProcedure(aText);
  
  if ThereAreMoreFramesAvailable then Chromium1.RetrieveHTML(NextFrameNameOrID);
end;
In this code you would need to create 3 procedures/functions :
  • MyCustomHTMLHandlingProcedure : This procedure saves the HTML.
  • ThereAreMoreFramesAvailable : This function will tell you if you need to call RetrieveHTML again with another frame name or id.
  • NextFrameNameOrID : This function will give the next unprocessed frame name or id.
leburaque
Posts: 1
Joined: Sun Nov 08, 2020 9:41 am

Re: how can i get source from an iframe?

Post by leburaque »

I do not know if someone will need information with a sample code that captures the whole thing on the fly. I had a bit of a problem understanding what and where works.

LoadUrl(needed_url);
WaitForBrowser; // my simple procedure that waits with TTimer some milliseconds to get HTML Source
frames := TStringList.Create;
Form1.Chromium1.GetFrameNames(frames);
s1 := frames[1]; // i always need exactly this one from list, but one can modify it and find other frames

// one does not need that part, but You can check here url for frame and even load frame to browser
// url_for_frame := Form1.Chromium1.Browser.GetFrame(url_for_frame).Url;
// LoadUrl(url_for_frame);

Form1.Chromium1.RetrieveHTML(s1);
WaitForBrowser;

after that, if You have some procedure like this (inherited event OnTextResultAvaible in Your TChromium, to html_result string will be pasted frame html code ready to parse - after waiting for browser ofc. :)

procedure Chromium1TextResultAvaible(Sender: TObject; const aText: ustring);
begin
Form1.Chromium1.RetrieveHTML(aText);
html_result := aText;
end;
Post Reply