Link to home
Start Free TrialLog in
Avatar of hibbidiji
hibbidiji

asked on

searching for text within a twebbrowser

I would like to take one action if a particular string appears on the page that is loaded by my twebbrowser and another if it doesnt.    How can I do this?   I'm not sure where I can get the html contents of the control.
Avatar of shaneholmes
shaneholmes

procedure TForm1.Button2Click(Sender: TObject);
var
  DOM : variant;
  SL: TStringList;
begin
  SL:= TSTringList.Create;
  DOM := WebBrowser1.Document;
  if Webbrowser1.LocationURL <> '' then
    begin
      SL.Text := DOM.Body.OuterHTML;
    end
    else
    begin
          ShowMessage('No page available!');
    end;
end;

Now you can iterate through the StringList and find what your looking for


ShaneHolmes
procedure TForm1.Button1Click(Sender: TObject);
var
 DOM : variant;
 SL: TSTringList;
 I: Integer;
begin
 WebBrowser1.Navigate('Www.google.com');
 DOM := WebBrowser1.Document;
 DOM.Body.OuterHTML;
 SL:= TSTringList.Create;
 SL.Text:= DOM.Body.OuterHTML;
 for I:= 0 to SL.Count - 1 do
 begin
  // if  Pos('SomeText', SL[I]) > 0 then
  // begin
  //  //do somthing
  // end;
 end;
end;

ShaneHolmes
Avatar of hibbidiji

ASKER

I have increased points to 400 because I need to further refine my question.

I need to parse some html within the strinlist that we're looping through.

It will look like this:
There are  <span class="ytext">4235</span> records.

I need to do a comparison of the number inside the class span.    If it is more than 40 I need to execute my "something"   if not, I need to do nothing.    I suck eggs at regexp so I could use some assistance.

Thanks, and if this question cant be answered by shaneholmes, shane will get 100% of the original points with the rest to the person who answers the rest.
Hi,

Use OnNavigateComplete event with the following code:

procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var
  doc: variant;
  sl: TStringList;
  s: string;
  i, k: integer;
  span: integer;
begin
  try
    sl := TStringList.Create;
    try
      doc := WebBrowser1.Document;
      sl.Text := doc.Body.OuterHTML;
      for i := 0 to sl.Count - 1 do begin
        k := Pos('<span', LowerCase(sl[i]));
        if k > 0 then begin
          s := Copy(sl[i], k + 5, Length(sl[i]));
          k := Pos('>', s);
          if k > 0 then begin
            s := Copy(s, k + 1, Length(sl[i]));
            k := Pos('<', s);
            if k > 0 then begin
              try
                span := StrToInt(Copy(s, 1, k - 1));
                if span > 40 then begin
                  // add your code here
                  // ....
                  break;
                end;
              except
              end;
            end;
          end;
        end;
      end;
    finally
      sl.Free;
    end;
  except
  end;
end;

Regards, Geo
I meant OnDocumentComplete event.
Avatar of Eddie Shipman
Here's how to do it using the DOM:

uses  ...,mshtml; // if using D6 or greater, else mshtml_tlb after importing the TypeLib

procedure TForm1.Button1Click(Sender: TObject);
begin
 { HTML source for span.html:
    <html>
      <head>
        <title>Untitled</title>
      </head>
      <body>
        <span class="ytext1">4235</span>
        <span class="ytext2">5</span>
        <span class="ytext3">35</span>
      </body>
    </html>
 }
  WB.Navigate('http://localhost/span.html');
end;

procedure TForm1.WBDocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
var
  doc: IHTMLDocument2;
  elements: IHTMLElementCollection;
  element: IHTMLElement;
  i:        Integer;
begin
  // Get the WebBrowser's Document into an IHTMLDocument2 object
  doc := WB.Document as IHTMLDocument2;
  // Get all the Span elements
  elements := doc.all.tags('SPAN') as IHTMLElementCollection;
  // iterate through them
  for i := 0 to elements.length-1 do
  begin
    select each element into an IHTMLElement object
    element := elements.item(i, '') as IHTMLElement;
    // Check to see if classname is OK, not sure if you want to do this.
    if Pos('ytext', element.className) > 0 then
    begin
      // May need to do more checking before this conversion if these spans contain other text.
      if StrToInt(Trimelement.innerText)) > 40 then
      begin
        ShowMessage('Found One: ' + element.innerText);
      end;
    end;
  end;
end;
Yes, there are many spans on the page that will use the same style AND have numeric values.   I like the idea of using dom, but I am at a loss as to how to use your example AND pay attention to the text around the spans
There are  <span class="ytext">4235</span> records.

Ideas?
"pay attention to the text around the spans"
I don't quite understand...

What do you need to do, exactly?
That's the question! What do you need? If there are many SPAN tags containing different numbers then what will you be searching for?
There may be 200 span tags containing a number

I am only interested in the one that contains the number of records.   It will be:
There are  <span class="ytext">(int here)</span> records.
every single time
ASKER CERTIFIED SOLUTION
Avatar of Eddie Shipman
Eddie Shipman
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Eddie,
  doc: IHTMLDocument2;
  elements: IHTMLElementCollection;
  element: IHTMLElement;

These are giving me errors.  do the names need to be changed to match something in my app?   Please forgive my ignorance on this.
to further clarify - I'm getting undeclared identifier errors
>uses  ...,mshtml; // if using D6 or greater, else mshtml_tlb after importing the TypeLib

Import 'Microsoft HTML Object Library' from 'Project-Import Type Library' menu.
I thought you had tried the last code I posted which would have told you to include
mshtml or mshtml_tlb in your uses... ;-)
I was only modifying the original code I posted.
working great. I apologize for being a dummy