Link to home
Start Free TrialLog in
Avatar of sal1150
sal1150

asked on

Again the data of html table

Before I post this question in this linke.
https://www.experts-exchange.com/questions/21271309/Take-data-from-web-page.html

But the web page addres changed so I want to parse the html table in stringgrid from this link
http://www.tadawul.com.sa/wps/portal/!ut/p/.cmd/cs/.ce/7_0_A/.s/7_0_4AI/_s.7_0_A/7_0_4AI/.cmd/ChangeLanguage/.l/en

You must reopen this linke twise to show the tabel without any addition page.
Avatar of Eddie Shipman
Eddie Shipman
Flag of United States of America image

And, does my XMLHTTP solution not work for you anymore?
Avatar of sal1150
sal1150

ASKER

HI EddieShipman
I have feeling you are still angry?!!!
yes your XMLHTTP solution not work for me.
I will work on it again. I don't understand, it worked before,
OK, they changed the output from XML to HTML, this should be pretty easy using the URL you supplied.
Try this now:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, COMObj, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP, MSHTML, ActiveX;

const
  HTMLUrl   = 'http://www.tadawul.com.sa/wps/portal/!ut/p/.cmd/cs/.ce/7_0_A/.s/7_0_4AI/_s.7_0_A/7_0_4AI/.cmd/ChangeLanguage/.l/en';

type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure GetTableData;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  i, x: Integer;
begin
  StringGrid1.ColWidths[0] := 108;
  x := (StringGrid1.Width-165) div 13;
  for i := 1 to 10 do
  begin
    StringGrid1.ColWidths[i] := x;
  end;
  StringGrid1.Cells[0, 0] := 'Company';
  StringGrid1.Cells[1, 0] := 'Last Price';
  StringGrid1.Cells[2, 0] := 'Last Vol';
  StringGrid1.Cells[3, 0] := 'Last Change Val';
  StringGrid1.Cells[4, 0] := 'Last Change %';
  StringGrid1.Cells[5, 0] := 'Cum # Trades';
  StringGrid1.Cells[6, 0] := 'Cum Vol';
  StringGrid1.Cells[7, 0] := 'Best Bid Price';
  StringGrid1.Cells[8, 0] := 'Best Bid Vol';
  StringGrid1.Cells[9, 0] := 'Best Off Price';
  StringGrid1.Cells[10, 0] := 'Best Off Vol';
  StringGrid1.Cells[11, 0] := 'Today Open';
  StringGrid1.Cells[12, 0] := 'Today High';
  StringGrid1.Cells[13, 0] := 'Today Low';
end;

procedure TForm1.GetTableData;
var
  i, j, k, x:  Integer;
  idhttp:     TidHTTP;
  LHTML:      String;
  IDoc:       IHTMLDocument2;
  v:          Variant;
  TableRows:  IHTMLElementCollection;
  TableRow:   IHTMLTableRow;
  TableCells: IHTMLElementCollection;
  TableCell:  IHTMLElement;
begin
  idhttp := TidHTTP.Create(Self);
  try
    LHTML := idHTTP.Get(HTMLUrl);
  finally
    idhttp.Free;
  end;
  Idoc:=CreateComObject(Class_HTMLDocument) as IHTMLDocument2;
  try
    IDoc.designMode:='on';
    while IDoc.readyState<>'complete' do
      Application.ProcessMessages;
    v:=VarArrayCreate([0,0],VarVariant);
    v[0]:= LHTML;
    IDoc.write(PSafeArray(System.TVarData(v).VArray));
    IDoc.designMode:='off';
    while IDoc.readyState<>'complete' do
      Application.ProcessMessages;
    // Get all tha tablerows
    TableRows := (iDoc.all.tags('TR') as IHTMLElementCollection);
    for i := 0 to TableRows.length-1 do
    begin
      TableRow := (TableRows.item(i, 0) as IHTMLTableRow);
      if Trim((TableRow as IHTMLELement).className) = 'regular' then
      begin
       if TableRow.cells.length > 2 then
       begin
         for j := 0 to TableRow.cells.length-1 do
         begin
           TableCell := (TableRow.cells.item(j,0) as IHTMLElement);
           StringGrid1.Cells[j, StringGrid1.RowCount-1] := TableCell.innerText;
         end;
         StringGrid1.RowCount := StringGrid1.RowCount + 1;
       end;
      end;
    end;
  finally
    IDoc  := nil;
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  GetTableData;
end;

end.
Avatar of sal1150

ASKER

HI EddieShipman
Not all companys comeing in stringgrid.
Avatar of sal1150

ASKER

good now all rows comming after I edit this line
if (Trim((TableRow as IHTMLELement).className) = 'regular') or (Trim((TableRow as IHTMLELement).className) = 'table_back')

but still I have tow problems
(1) there are 3 extra rows in grid without data (blank) [row no 1,2 and 3].

(2) I need the code of each company in grid for exmple:
RIBL its code is 1010 (after 'symbol=')
href="http://www.tadawul.com.sa/wps/portal/!ut/p/_s.7_0_A/7_0_4BC?tabOrder=1&symbol=1010">RIBL
Avatar of sal1150

ASKER

I solve the first problem by changing
StringGrid1.RowCount:=1; at desing time.

Now my problem only symbol of company without it I cant worke because it is aprimary key in my database.
OK, give me a few minutes...
Make these changes: (be sure to set stringgrid colcount to 15)
I don't get any empty rows except one at the bottom.

procedure TForm1.GetTableData;
var
  i, j, k, x:  Integer;
  idhttp:     TidHTTP;
  LHTML:      String;
  IDoc:       IHTMLDocument2;
  v:          Variant;
  TableRows:  IHTMLElementCollection;
  TableRow:   IHTMLTableRow;
  TableCells: IHTMLElementCollection;
  TableCell:  IHTMLElement;
  LSymbol:    String;
  LPos1:      Integer;
  LPos2:      Integer;
begin
  idhttp := TidHTTP.Create(Self);
  try
    LHTML := idHTTP.Get(HTMLUrl);
  finally
    idhttp.Free;
  end;
  Idoc:=CreateComObject(Class_HTMLDocument) as IHTMLDocument2;
  try
    IDoc.designMode:='on';
    while IDoc.readyState<>'complete' do
      Application.ProcessMessages;
    v:=VarArrayCreate([0,0],VarVariant);
    v[0]:= LHTML;
    IDoc.write(PSafeArray(System.TVarData(v).VArray));
    IDoc.designMode:='off';
    while IDoc.readyState<>'complete' do
      Application.ProcessMessages;
    // Get all tha tablerows
    TableRows := (iDoc.all.tags('TR') as IHTMLElementCollection);
    for i := 0 to TableRows.length-1 do
    begin
      TableRow := (TableRows.item(i, 0) as IHTMLTableRow);
      if (Trim((TableRow as IHTMLELement).className) = 'regular') or
         (Trim((TableRow as IHTMLELement).className) = 'table_back') then
      begin
       if TableRow.cells.length > 2 then
       begin
         for j := 0 to TableRow.cells.length-1 do
         begin
             TableCell := (TableRow.cells.item(j,0) as IHTMLElement);                                              //
             if j = 0 then
             begin
               LPos1 := Pos('symbol=', TableCell.outerHTML)+7;
               LPos2 := Pos('">'+ TableCell.innerText, TableCell.outerHTML)-LPos1;
               LSymbol := Copy(TableCell.outerHTML, Lpos1, LPos2);
               StringGrid1.Cells[j, StringGrid1.RowCount-1] := LSymbol;
               StringGrid1.Cells[j+1, StringGrid1.RowCount-1] := TableCell.innerText;
             end
             else
               StringGrid1.Cells[j+1, StringGrid1.RowCount-1] := TableCell.innerText;
         end;
         StringGrid1.RowCount := StringGrid1.RowCount + 1;
       end;
      end;
    end;
  finally
    IDoc  := nil;
  end;
end;
Avatar of sal1150

ASKER

good but company name not comeing
Comes for me. I see RIBL in second column.
Avatar of sal1150

ASKER

sorry they are coming....but the symbol not coming for all the company
look at this when I change the htmlurl to arabic page.



const
  HTMLUrl   = 'http://www.tadawul.com.sa/wps/portal/!ut/p/.cmd/cs/.ce/7_0_A/.s/7_0_4AI/_s.7_0_A/7_0_4AI/.cmd/ChangeLanguage/.l/ar';


procedure TForm1.Button2Click(Sender: TObject);
var
  i, j, k, x:  Integer;
  idhttp:     TidHTTP;
  LHTML:      String;
  IDoc:       IHTMLDocument2;
  v:          Variant;
  TableRows:  IHTMLElementCollection;
  TableRow:   IHTMLTableRow;
  TableCells: IHTMLElementCollection;
  TableCell:  IHTMLElement;
  LSymbol:    String;
  LPos1:      Integer;
  LPos2:      Integer;
begin
  idhttp := TidHTTP.Create(Self);
  try
    LHTML := idHTTP.Get(HTMLUrl);
  finally
    idhttp.Free;
  end;
  Idoc:=CreateComObject(Class_HTMLDocument) as IHTMLDocument2;
  try
    IDoc.designMode:='on';
    while IDoc.readyState<>'complete' do
      Application.ProcessMessages;
    v:=VarArrayCreate([0,0],VarVariant);
    v[0]:= LHTML;
    IDoc.write(PSafeArray(System.TVarData(v).VArray));
    IDoc.designMode:='off';
    while IDoc.readyState<>'complete' do
      Application.ProcessMessages;
    // Get all tha tablerows
    TableRows := (iDoc.all.tags('TR') as IHTMLElementCollection);
    for i := 0 to TableRows.length-1 do
    begin
      TableRow := (TableRows.item(i, 0) as IHTMLTableRow);
      if (Trim((TableRow as IHTMLELement).className) = 'regular') or
         (Trim((TableRow as IHTMLELement).className) = 'table_back') then
      begin
       if TableRow.cells.length > 2 then
       begin
         for j := 0 to TableRow.cells.length-1 do
         begin
             TableCell := (TableRow.cells.item(j,0) as IHTMLElement);                                              //
             if j = 0 then
             begin
               LPos1 := Pos('symbol=', TableCell.outerHTML)+7;
               LPos2 := Pos('">'+ TableCell.innerText, TableCell.outerHTML)-LPos1;
               LSymbol := Copy(TableCell.outerHTML, Lpos1, LPos2);
               StringGrid1.Cells[0, StringGrid1.RowCount] := LSymbol;
               StringGrid1.Cells[j+1, StringGrid1.RowCount] := UTF8Decode(TableCell.innerText);
             end
             else
               StringGrid1.Cells[j+1, StringGrid1.RowCount] := UTF8Decode(TableCell.innerText);

         end;
         StringGrid1.RowCount := StringGrid1.RowCount + 1;
         StringGrid1.FixedRows :=1;
       end;
      end;
    end;
  finally
    IDoc  := nil;
  end;
end;



procedure TForm1.FormCreate(Sender: TObject);
var
  i, x: Integer;
begin

  StringGrid1.ColCount :=15;
  StringGrid1.Cells[0, 0] := 'Code';
  StringGrid1.Cells[1, 0] := 'Company';
  StringGrid1.Cells[2, 0] := 'Last Price';
  StringGrid1.Cells[3, 0] := 'Last Vol';
  StringGrid1.Cells[4, 0] := 'Last Change Val';
  StringGrid1.Cells[5, 0] := 'Last Change %';
  StringGrid1.Cells[6, 0] := 'Cum # Trades';
  StringGrid1.Cells[7, 0] := 'Cum Vol';
  StringGrid1.Cells[8, 0] := 'Best Bid Price';
  StringGrid1.Cells[9, 0] := 'Best Bid Vol';
  StringGrid1.Cells[10, 0] := 'Best Off Price';
  StringGrid1.Cells[11, 0] := 'Best Off Vol';
  StringGrid1.Cells[12, 0] := 'Today Open';
  StringGrid1.Cells[13, 0] := 'Today High';
  StringGrid1.Cells[14, 0] := 'Today Low';
end;
Avatar of sal1150

ASKER

some company with nul value.
Avatar of sal1150

ASKER

I think the problem in the 'href' lenght
for example
this href coming in one line in the html source

href="http://www.tadawul.com.sa/wps/portal/!ut/p/_s.7_0_A/7_0_4BC?tabOrder=1&symbol=2060">Industrialization</A></TD>

but another they are coming in tow lines.
Avatar of sal1150

ASKER

for english page only the herf come with null value

href="http://www.tadawul.com.sa/wps/portal/!ut/p/_s.7_0_A/7_0_4BC?tabOrder=1&symbol=2080">Gas&amp;Industrialization</A></TD>

Well, modify these lines to get the desired result.

 LPos1 := Pos('symbol=', TableCell.outerHTML)+7;
LPos2 := Pos('">'+ TableCell.innerText, TableCell.outerHTML)-LPos1;
LSymbol := Copy(TableCell.outerHTML, Lpos1, LPos2);
StringGrid1.Cells[0, StringGrid1.RowCount] := LSymbol;

Can't you figure it out from here?
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