delphi初心者です。よろしくお願いします。
delphiを用いて、Webプログラムをつくっています。
簡単なWebブラウザなどは作成することができたのですが、
1.googleなどの検索エンジンを用いて、検索を行い、
リストアップされた検索結果のHTMLソースを取得する。
2.取得したHTMLソースからURL部分のみを抜き出し、保持する。
3.保持したそれぞれのURLを子ウィンドに反映させて表示させる。
というようなことを行うプログラムを作成したくて、
いろいろ試したのですが、delphi初心者なものでどうもうまくいきません。
すみませんが教えて頂けないでしょうか?よろしくお願いします。
簡単に出来ますが、
1,2,3のどのあたりができないのですか?
KHE00221様
ご指摘ありがとうございます。そうですよね。どの部分がわかっていないか明確に書かなくてはいけませんよね。申し訳ありません。
1の部分はなんとかできそうなのですが、2と3の部分がどのようにすればいいのか全く検討がつかない状況なのです。。
いろいろ調べてはいるのですが、なかなか参考になるものが見つからなくて、困っている状況です。なにかアドバイスを頂けたら嬉しいのですが、
よろしくお願いします。
正直、初心者の方には少し難しいプログラムだと思いますけど。
抽出したいURLは<a href></a>タグなどでリンクされてるものだけでよいでしょうか?それとも、ソースの中で"http://…"の形式になっている文字列は全部拾う必要がありますか?
あと相対的なURL指定(<a href="./abc/def.html">みたいな形式)のものも抽出する必要がありますか?
その辺でプログラムの書き方が変わってくるのですけど。
>3.保持したそれぞれのURLを子ウィンドに反映させて表示させる。
これも意味がよくわかりません。子ウィンドウにブラウザみたいなもので表示したいのですか?
さなみ様
やはりちょっとハードルが高いですか、、
難しいとは思うのですが、なんとかがんばってみたいと思っています。
私が作成したいプログラムは、googleであるワードの検索を行い、その検索結果のURLを取得・保存し、そのURLを子ウインドに反映するということを書いているのですが、、
例えば、googleで「delphi」と検索した場合、
1.Delphi
2.Delphi - Wikipedia
3.フリーのTurbo Delphiで始めるWindowsプログラミング:ITpro
・
(中略)
・
10.クジラ式 Delphi 資料
というようにリスト化された検索結果が出ると思いますが、この1〜10
のそれぞれURLを取得・保存して、それぞれを子ウインドのブラウザで表示
できるようなプログラムです。
このプログラムのURL取得の方法はさなみ様が言われた「<a href></a>タグなどでリンクされてるもの」の方法でいけると考えているのですが。。
いろいろ方法があれば、勉強したいと思いますので、アドバイス等ありましたら、よろしくお願いします。
すべでの <a の中から リンク先のみをどう探すかが問題になると思いますが、
1つの検索結果は
<div class="g">
<h2 class=r>
<a href="リンク先">サイト名</a>
</h2>
<table>
サイトの中身
</table>
</div>
となっているようです
この辺を考慮して作成すれば良いでしょう。
>それぞれを子ウインドのブラウザで表示できるようなプログラムです。
これはつまり IE を10個起動したような状態 にするという事ですか?
それならば TWebBrowser を貼り付けたフォームを作成し
WebBrowser1.Navigate('http://www.google.co.jp/'); 等とすれば
表示する事が可能となります(実際には取得したアドレスを設定)
ShellExecute( Application.Handle,'','http://www.google.co.jp/',
'','',1);
として直接ブラウザを起動させる方法もありますが
KHE00221様
アドバイスありがとうございます。
そうなんですよね。リンク先のみをどう取得するかが課題なんです。
URLを取得できたとしても、検索結果以外のリンクも取得してしまうと思われるので、検索結果のURLだけを取得するような、いい方法がないか考えているところです。。
それぞれを子ウインドのブラウザで表示できるようなプログラム。
これは、MDIの機能を用いて行いたいと考えています。
KHE00221様が書かれているように、IEを10個起動したようなものですね。
取得・保存したURLをMDIのchildに反映できればと考えているのですが、
この部分もなかなかいい方法が見つからない状態です・・・
またアドバイス等ありましたら、よろしくお願いします。
>YUI様
1と2についてのサンプルです。
正規表現ライブラリを使っていますが、
http://delwiki.info/?%A5%B3%A5%F3%A5%DD%A1%BC%A5%CD%A5%F3%A5%C8%2FTRegExpr
の「TRegExpr クラスを使う」を参考にしてください。
環境 : Del6 Pro
<準備>
①
http://www.regexpstudio.com/Downloads/regexpr.zip
をダウンロード・解凍し、"Sorce"フォルダの中にある"RegExpr.pas"をプロジェクトフォルダの中にコピーしてください。
②
uses節に、「RegExpr」と「HTTPApp」を追加してください。
>Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
>Dialogs,RegExpr,HTTPApp;
③
"FastNet"タブにあるTNMHTTPコンポーネントをフォームの上に貼り付けてください。名前は"NMHTTP1"のままでよいです。
<サンプル>
//検索結果のURLリストをダイアログで表示します
procedure TForm1.Button1Click(Sender: TObject);
var
KensakuWord:string;
URL:string;
Source:string;
r:TRegExpr;
Kekka:string;
begin
//Googleで検索する単語を指定
KensakuWord:='プログラミング';
//ソースを取得するURL
URL:='http://www.google.co.jp/search?hl=ja&q='+HTTPEncode(KensakuWord);
//NTHTTPコンポーネントでソースを取得
NMHTTP1.Get(URL);
Source:=NMHTTP1.Body;
//TRegExprクラスを使ってURLを抽出
Kekka:='';
r := TRegExpr.Create;
try
r.Expression :='<h2 class=r><a href="([^"]+)"';
if r.Exec(Source) then
begin
repeat
Kekka:=Kekka + r.Match[1] + #13#10;
until not r.ExecNext;
end;
finally
r.Free;
end;
//結果を表示
ShowMessage(Kekka);
end;
UNIT1 を MDIForm UNIT2 を MDIChild にして下さい。
UNIT2 と UNIT99 を プロジェクトから削除して下さい。
ディスク上に保存した google の検索結果の HTML を対象にしています
--------------------------------------------------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StrUtils, StdCtrls;
type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses Unit2,Unit99;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
I,J1,J2,J3,J4,Index : Integer;
StringList : TStringList;
S : String;
F0 : Boolean;
begin
if OpenDialog1.Execute = True then
begin
StringList := TStringList.Create;
StringList.LoadFromFile(OpenDialog1.FileName);
for I:=0 to StringList.Count -1 do
begin
Index := 1;
S := StringList[I];
F0 := False;
while F0 = False do
begin
F0 := True;
J1 := PosEx('<h2 class=r>',S,Index);
if J1 <> 0 then
begin
J2 := PosEX('<a href="',S,J1+12);
if J2 <> 0 then
begin
J3 := PosEx('" class=l',S,J2+9);
if J3 <> 0 then
begin
Form2 := TForm2.Create(Self);
Form2.WebBrowser1.Navigate(Copy(S,J2+9,J3-J2-9));
J4 := PosEx('</h2>',S,J3+9);
if J4 <> 0 then
begin
Index := J4;
F0 := False;
end;
end;
end;
end;
end;
end;
StringList.Free;
end;
end;
end.
----------------------------------------------------------
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleCtrls, SHDocVw;
type
TForm2 = class(TForm)
WebBrowser1: TWebBrowser;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
implementation
{$R *.dfm}
uses
Unit99;
procedure TForm2.FormCreate(Sender: TObject);
begin
FormList.Add(Pointer(Self));
Exit;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Release;
end;
procedure TForm2.FormDestroy(Sender: TObject);
var
I : Integer;
begin
I := FormList.IndexOf(Pointer(Self));
if I <> -1 then
begin
FormList.Delete(I);
end;
end;
end.
----------------------------------------------------------------
unit Unit99;
interface
uses
Classes,Unit1,Unit2;
var
Form2 : TForm2;
FormList : TList;
implementation
initialization
FormList := TList.Create;
finalization
FormList.Free;
end.
さなみ様
アドバイスありがとうございます。返事が遅くなり申し訳ありません。
さなみ様にアドバイスして頂いた方法で、プログラムを作成しようとしたのですが、私のdelphiには「FastNet」のタブがなく、googleでいろいろ調べたのですが、このコンポーネントをどうインストールしたらいいのかわからない状態です。。。
環境はdelphi7のproなんですが、7には「FastNet」はないのでしょうか??
質問ばかりですみません。
KHE00221様
アドバイスありがとうございます。非常に参考になるプログラムなので、頂いたソースでプログラムを1度作成してみようと試みたのですが、やり方がおかしいのか、どうもうまくいきません。。。
頂いたプログラムをMDIアプリケーションとして、作っていけばいいと思っていたのですが、、
前回のコメントで
>UNIT1 を MDIForm UNIT2 を MDIChild にして下さい。
この部分の意味は理解できるのですが、、
unit1はMAIN、unit2はCHILDWINとして扱うという意味ですよね??
>UNIT2 と UNIT99 を プロジェクトから削除して下さい。
この部分はどういう意味なのでしょうか??
質問ばかりで本当に申し訳ありませんが、アドバイスお願い致します。
Yahooであれば、Yahoo検索APIなどを使えばXML形式で取得できますよ。
http://developer.yahoo.co.jp/
GoogleだとGoogle Web APIsです。
名称が変わっているかもしれませんが。
http://code.google.com/intl/ja/apis/
>UNIT1 を MDIForm UNIT2 を MDIChild にして下さい。
この部分の意味は理解できるのですが、、
unit1はMAIN、unit2はCHILDWINとして扱うという意味ですよね??
FormStyle を Unit1 は fsMDIForm Unit2 は fsMDIChild にして下さい
>UNIT2 と UNIT99 を プロジェクトから削除して下さい。
この部分はどういう意味なのでしょうか??
質問ばかりで本当に申し訳ありませんが、アドバイスお願い致します
メニューの プロジェクト -> プロジェクトの削除 を実行すると
ユニットの一覧が表示されますので、Unit2 と Unit99 を選択して OK
を押してくださいそうすると プロジェクト -> ソース表示 で表示されるソースが
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit99 in 'Unit99.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
から
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
変更されます。
削除しないと正常に動作しません
>YUI様
では、NetFastの代わりにIndyを使いましょう。
Del7にも入っていると思います。
上の書き込みの<準備>のTNMHTTPコンポーネントの代わりに「Indy Clients」タブにあるIdHTTPコンポーネントをフォームに貼り付けてください。
名前は「IdHTTP1」のままで良いです。
その後、IdHTTP1のRequestプロパティのUserAgentプロパティを
Mozilla/3.0 (compatible; Indy Library)
↓から
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
に書き換えておいてください。
上の書き込みの<サンプル>を以下のように修正してください。
---修正前---
//NTHTTPコンポーネントでソースを取得
NMHTTP1.Get(URL);
Source:=NMHTTP1.Body;
---修正後---
//IdHTTPコンポーネントでソースを取得
Source:=IdHTTP1.Get(URL);
にしの様
アドバイスありがとうございます。API、とても勉強になりました。いろいろ勉強していきたいと思っているので、またアドバイス等ありましたら、よろしくお願いします。
さなみ様
アドバイスありがとうございます。ご指摘頂いた方法で、URLを取得することができました。
何度もアドバイスしていただき、本当にありがとうございます。また質問することがあるかもしれませんが、その時はよろしくお願いします。
KHE00221様
何度も親切にありがとうございます。頂いたプログラムを完成することができました。非常に参考になるプログラムでした。本当にありがとうございます。
これから保存したものではなく、ブラウザから直接操作できるようにしていきたいと思っています。また質問等することがあるかもしれませんが、その時はアドバイスよろしくお願いします。
自分なりに作ってみました
http://khe00221.image.coocan.jp/index.php?FrontPage%2FApplication%2FGoogle%B8%A1%BA%F7%B7%AF
ソース付きでダウンロード可能です
BDS2006
迷惑投稿防止対策で半角文字だけの投稿は出来ないはずなのに...ナゼ?と思って内容をヨク見てみたら、
これ↓があるからチェックをすり抜けたのかな...
>citt鐃ス
>societ鐃ス
最近この手のスパムが多い。
phpだったら...
strlen と mb_strlen の合わせ技なんかの組み合わせではねたり
更にリンク(http://)の数を制限するとか..にするけど、
ここはperlみたいだから何か似たような
手を打たないと最近は半角文字のみでは多分無理と思う・・・
ツイート | ![]() |