大家好!先对大家即将给我得帮助表示诚挚的感谢!
本人一直钟情于Delphi的学习,由于工作的原因一直断断续续的,最近弄出了个新念头,想弄一个Delphi的数据采集程序,譬如说在Edit中输入某一网址和采集数据的类型(文本、超链接、图片之类的),点击启动采集按钮后,能够在下面的listview中看到采集的数据。
希望各位哥哥姐姐帮帮忙,Delphi的数据采集一般用什么组件和命令。
谢谢!

解决方案 »

  1.   

    貌似用 TWebBrowser 更快些,里面的锚点、链接、等等有数组。indyhttp 的话,只能分析txt了
      

  2.   

    原文:http://www.iecn.cn/blog-html-do-showone-itemid-988-type-blog.html 采集程序原理采集程序的主要步骤如下:一、获取被采集的页面的内容
    二、从获取代码中提取所有用的数据
    一、获取被采集的页面的内容
    我目前所掌握的ASP常用获取被采集的页面的内容方法:
    1、用serverXMLHTTP组件获取数据以下内容为程序代码:Function GetBody(weburl)  
        '创建对象
        Dim ObjXMLHTTP
        Set ObjXMLHTTP=Server.CreateObject("MSXML2.serverXMLHTTP")
        '请求文件,以异步形式
        ObjXMLHTTP.Open "GET",weburl,False
        ObjXMLHTTP.send
        While ObjXMLHTTP.readyState <> 4
            ObjXMLHTTP.waitForResponse 1000
        Wend
        '得到结果
         GetBody=ObjXMLHTTP.responseBody
        '释放对象
         Set ObjXMLHTTP=Nothing
    End Function
    调用方法:
    GetBody(文件的URLf地址) 
    2、或XMLHTTP组件获取数据以下内容为程序代码:Function GetBody(weburl)   
        '创建对象
        Set Retrieval = CreateObject("Microsoft.XMLHTTP") 
        With Retrieval 
         .Open "Get", weburl, False, "", "" 
         .Send 
         GetBody = .ResponseBody
         End With 
        '释放对象
        Set Retrieval = Nothing 
    End Function
    调用方法:
    GetBody(文件的URLf地址) 
    这样获取的数据内容还需要进行编码转换才可以使用以下内容为程序代码:Function BytesToBstr(body,Cset) 
            dim objstream
            set objstream = Server.CreateObject("adodb.stream")
            objstream.Type = 1
            objstream.Mode =3
            objstream.Open
            objstream.Write body
            objstream.Position = 0
            objstream.Type = 2
            objstream.Charset = Cset
            BytesToBstr = objstream.ReadText 
            objstream.Close
            set objstream = nothing
    End Function
    调用方法:BytesToBstr(要转换的数据,编码)'编码常用为GB2312和UTF-8
    二、从获取代码中提取所有用的数据
    目前我掌握的方法有:
    1、用ASP内置的MID函数截取需要的数据以下内容为程序代码:Function body(wstr,start,over)
    start=Newstring(wstr,start)
    '设置需要处理的数据的唯一的开始标记
    over=Newstring(wstr,over)
    '和start相对应的就是需要处理的数据的唯一的结束标记
    body=mid(wstr,start,over-start)
    '设置显示页面的范围End Function
    调用方法:body(被采集的页面的内容,开始标记,结束标记)
    2、用正则获取需要的数据以下内容为程序代码:Function body(wstr,start,over)
    Set xiaoqi = New Regexp'设置配置对象
    xiaoqi.IgnoreCase = True'忽略大小写
    xiaoqi.Global = True'设置为全文搜索
    xiaoqi.Pattern =  "”&start&“.+?”&over&“"'正则表达式 
    Set Matches =xiaoqi.Execute(wstr)'开始执行配置
    set  xiaoqi=nothing 
    body=""
    For Each Match in Matches
    body=body&Match.Value '循环匹配
    Next
    End Function
    调用方法:body(被采集的页面的内容,开始标记,结束标记)
    采集程序祥细思路:
    1、取得网站的分页列表页的每页地址
    目前绝大部分动态网站的分页地址都有规则,如:
    动态页
    第一页:index.asp?page=1
    第二页:index.asp?page=2
    第三页:index.asp?page=3
    .....
    静态页
    第一页:page_1.htm
    第二页:page_2.htm
    第三页:page_3.htm
    .....
    取得网站的分页列表页的每页地址,只需要用变量替代每页地址的变化的字符即可如:page_<%="&page&"%>.htm
    2、获取被采集网站的分页列表页内容
    3、从分页列表代码中提取被采集的内容页面的URL连接地址
    绝大部分分页页面里的内容页连接也有固定规则,如:
    连接1 连接2 连接3 用以下代码就可以获得一个URL连接集合以下内容为程序代码:
    Set xiaoqi = New Regexp
    xiaoqi.IgnoreCase = True
    xiaoqi.Global = True
    xiaoqi.Pattern =  ””“.+?”““
    Set Matches =xiaoqi.Execute(页面列表内容)
    set  xiaoqi=nothing 
    url=""
    For Each Match in Matches
    url=url&Match.Value 
    Next
    4、取得被采集的内容页面内容,根据”提取标记“从被采集的内容页面分别截取要取得的数据
    因为是动态生成的页面,大多数内容页面内都有相同的html标记,我们可以根据这些有规则的标记提取需要的各个部分的内容。
    如:
    每个页面都有网页标题,用我上面写的MID截取函数就可以获得之间的值,也可以用正则表达式来获得。
    例:body("","") 
    google :http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Azh-CN%3Aofficial&hs=peC&q=web+%E9%A1%B5%E9%9D%A2%E5%86%85%E5%AE%B9%E9%87%87%E9%9B%86+%E5%8E%9F%E7%90%86&btnG=Search虽然这些并不是直接用 delphi,但是delphi都可以使用这些对象。
      

  3.   

    indy中的idhttp
    使用idhttp的get方法
    另外你需要学习一下线程方面的知识
      

  4.   

    很厉害嘛!
    谢谢!
    但是问题是一直没学过和用过Asp和VB,所以很困难去理解里面的东西和你说给的知识转化为Delphi的程序代码!
    不知道你用过Delphi没有啊!如果用过,帮忙给点Delphi的东西吗!谢谢!如果哪位哥哥姐姐做过这方面的小程序(Delphi的网页数据采集,自动采集给以网站名称的数据和更新数据的程序),发给小弟,小弟邮箱是:[email protected] 小弟我将在多给以30分以答谢哥哥姐姐的好意!
    在此深深的谢意!
    如果哪位哥哥姐姐愿意与小弟交谈,可以留下联系方式!
    在此深深的谢意!
    感激之至!溢于言表!
      

  5.   

    只是获得网页的内容,给你段代码参考:用IdHttpvar
        strIndexURL:string;
    begin
        strIndexURL:='http://www.p5w.net/news/gncj/';
        CatchDataCustom(strIndexURL,'国内财经','GNCJ',IndexGNCJ);
    end;procedure TMainForm.CatchDataCustom(strURL:string;strTitleToken:string;strDatabaseToken:string;index:integer);
    var
        fs:TMemoryStream;
        strTemp:string;
        strLine:string;    strTitle,strText,strTime,strSource:string;
        dtTime:TDateTime;    strAuthor:string;
        dtTimeMax:TDateTime;
        strIndexURL:string;
        ucTemp:TUltraConnect;
    {
        TUltraConnect=record
            strTitle:string;
            strURL:string;
            strTime:string;
        end;
    }
    begin
        strIndexURL:=strURL;
        IdHTTP1.Disconnect;
        fs:=TMemoryStream.Create;
        dtTimeMax:=0;
        try
            IdHTTP1.Get(strIndexURL,fs);
            fs.Position:=0;
            Memo1.Lines.LoadFromStream(fs);
            strTemp:=Memo1.Lines.Text;
            strTemp:=Copy(strTemp,pos('文档列表',strTemp),Length(strTemp));
            strTemp:=GetStringBetween2(strTemp,'<Documents>','</Documents>');
            ucTemp.strTitle:='';
            while true do
            begin
                ucTemp:=GetConnectInfo(strTemp);
                if ucTemp.strTitle<>'' then
                begin
                    strTime:=ucTemp.strTime;
                    dtTime:=StrToDateTime('2006-'+strTime);
                    dtTimeMax:=max(dtTime,dtTimeMax);
                    if LastTimes[IndexGNCJ]<>'' then
                        if dtTime<=StrToDateTime(LastTimes[index]) then
                            break;
                    strTitle:=ucTemp.strTitle;
                    if(GetURLScript(strTitleToken,ucTemp.strURL,strText,strAuthor,strSource)) then
                    begin
                        AddDataBaseInfo(strDatabaseToken,strTitle,strText,dtTime,strSource,strAuthor);
                        Application.ProcessMessages;
                    end;
                end else
                    break;
            end;
        except
        end;
        fs.Free;
    end;
      

  6.   

    type
      TWebForm = class(TForm)
        BitBtn1: TBitBtn;
        idh1: TIdHTTP;
        Memo1: TMemo;
        Button1: TButton;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        idh2: TIdHTTP;
        procedure BitBtn1Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        getWeb:Tmemorystream; //TStringList;
        weburl:String;
        strTitle:String;
        strAuthor:String;
        strCopyFrom:String;
        strContent:String;
        StrSource:String;
        StrBegin:String;
        StrEnd:String;
        function Get(AURL:String):String;
        function GetStr(StrSource,StrBegin,StrEnd:String):String;
        { Public declarations }
      end;var
      WebForm: TWebForm;implementation
    function TWebForm.Get(AURL:string):string;
    begin
      result:='';
    end;function TWebForm.GetStr(StrSource,StrBegin,StrEnd:String):String;
    var
    in_star,in_end:integer;
    begin
      in_star:=AnsiPos(StrBegin,StrSource)+length(StrBegin);
      in_end:=AnsiPos(StrEnd,StrSource);
      result:=copy(StrSource,in_star,in_end-in_star);
    {
      函数里的AnsiPos和copy,都是系统定义的,可从delphi的帮助文件里找到相关说明,
      function AnsiPos(const Substr, S: string): Integer
      返回Substr在S中第一次出现的位置。
      function copy(strsource,in_star,in_end-in_star): string;
      返回字符串strsource中,从in_star(整型数据)开始到in_end-in_star(整型数据)结束的字符串。
    }
    end;{$R *.dfm}procedure TWebForm.BitBtn1Click(Sender: TObject);
    begin
      If Edit1.Text='' then
        Showmessage('请输入网址后再点击‘开始采集’按钮!')
      else
      try
      begin
        Memo1.Text:='';
        weburl:=Edit1.Text;
        getWeb:=Tmemorystream.Create; 
        idh2.Get(weburl);
        idh1.Get(weburl,getWeb);
        StrSource:=idh2.Get(weburl);
        strTitle:=GetStr(StrSource,'<table><b>','</b></table>');
        strAuthor:=GetStr(StrSource,'<table><tr>','</tr></table>');
        strCopyFrom:=GetStr(StrSource,'<table><tr>','</tr></table>');
        strContent:=GetStr(StrSource,'<table><tr>','</tr></table>');
        Edit2.Enabled:=True;
        Edit2.Text:=IntToStr(getWeb.Size);
        Edit2.Enabled:=False;
        Memo1.Lines.Text:=strTitle;
        Memo1.Lines.Append(strAuthor);
        Memo1.Lines.Append(strCopyFrom);
        Memo1.Lines.Append(strContent);
        getWeb.Free;
      end;
      except
      begin
        Showmessage('访问数据不成功或你所输入的网址不存在!');
        Memo1.Clear;
      end;
      end;
    end;procedure TWebForm.Button1Click(Sender: TObject);
    begin
    If Application.MessageBox('您真的要退出系统吗?','WebForm提示!',mb_yesno)=idyes then
      begin
        WebForm.Close;
      end;
    end;procedure TWebForm.FormCreate(Sender: TObject);
    begin
      Memo1.Text:='欢迎使用Ruolin_Web网页采集程序!';
      Edit1.Text:='';
      Edit2.Enabled:=False;
    end;end.各位哥哥姐姐大家好!以上是我的代码,确实能够获得网页的内容,可是现在我只想获得网页中的部分信息,
    网址:http://212.56.159.148/astra/home/vis_quote.php?sub=3295&sel_data=0
    我只想获得这个网址中的表格里的内容和标题"Euro 2008 - Matches",把表格里的内容采下来存在记事本中,大体格式如下:
             M             Evento               Data          1   X    2 
    189372  S  Switzerland-Czech Republic 07/06/2008 18:00 2.90 3.10 2.40 
    189373  S  Portugal-Turkey            07/06/2008 20:45 1.75 3.35 4.75 
    189378  S  Austria-Croatia            08/06/2008 18:00 4.30 3.40 1.80 
    189379  S  Germany-Poland             08/06/2008 20:45 1.52 3.60 6.75 
    189384  S  Romania-France             09/06/2008 18:00 4.65 3.40 1.75 
    189385  S  Holland-Italy              09/06/2008 20:45 3.00 3.10 2.35 
    189392  S  Spain-Russia               10/06/2008 18:00 1.70 3.40 5.00 
    目的是要达到这个效果,希望各位哥哥姐姐帮忙修改哈!小弟实在是弄不出来了!
    如果哪位哥哥姐姐做过这方面的小程序(Delphi的网页数据采集,自动采集给以网站名称的数据和更新数据的程序),发给小弟,小弟邮箱是:[email protected] 小弟我将在多给以30分以答谢哥哥姐姐的好意! 
    在此深深的谢意! 
    如果哪位哥哥姐姐愿意与小弟交谈,可以留下联系方式! 
    在此深深的谢意! 
    感激之至!溢于言表!
      

  7.   

    如果只是页上的直接引用信息还比较好办,但如果是间接引用,或者是用Jsp生成的资源就不好办了。