zoukankan      html  css  js  c++  java
  • DELPHI读取网页源文件和获取字符串

    说到网页采集,通常大家以为到网上偷数据,然后把到收集到的数据挂到自己网上去。其实也可以将采集到的数据做为公司的参考,或把收集的数据跟自己公司的业务做对比等。
    目前网页采集多为3P代码为多(3P即ASP、PHP 、JSP)。用得最有代表的就动易科技公司BBS中新闻采集系统,和网上流传的新浪新闻采集系统等都是用ASP程序来使用,但速度从理论上来说不是很好。如果尝试用其它软件的多线程采集是不是更快?答案是肯定的。用DELPHI、VC、VB、JB都可以,PB似乎比较不好做。以下用DELPHI来解释采集网页数据。
    一、 简单的新闻采集
    新闻采集是最简单的,只要识别标题、副题、作者、出处、日期、新闻主体、分页就可以了。在采集之前肯定要取得网页的内容,所以在DELPHI里加入idHTTP控件(在indy Clients面板),然后用idHTTP1.GET 方法取得网页的内容,声明如下:
    function Get(AURL: string): string; overload;
    AURL参数,是string类型,指定一个URL地址字符串。函数返回也是string类型,返回网页的HTML源文件。比如我们可以这样调用:
    tmpStr:= idHTTP1.Get(‘http://www.163.com’);
    调用成功后,tmpstr变量里存储的就是网易主页的代码了。
    接下来,讲一下数据的截取,这里,我定义了这么一个函数:
    function TForm1.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_sta,in_end-in_star);
    end;
    StrSource:string类型,表示HTML源文件。
    StrBegin:string类型,表示截取开始的标记。
    StrEnd:string,表示截取结束的标记。
    函数返回字符串StrSource中从StrSource到StrBegin之间的一段文本。
    比如:
    strtmp:=TForm1.GetStr(‘A123BCD’,‘A’,‘BC’);
    运行后,strtmp的值为:’123’。
    关于函数里用到的AnsiPos和copy,都是系统定义的,可以从delphi的帮助文件里找到相关说明,我在这里也简单罗嗦一下:
    function AnsiPos(const Substr, S: string): Integer
    返回Substr在S中第一次出现的位置。
    function copy(strsource,in_sta,in_end-in_star): string;
    返回字符串strsource中,从in_sta(整型数据)开始到in_end-in_star(整型数据)结束的字符串。
    有了以上函数,我们就可以通过设置各种标记,来截取想要的文章内容了。在程序中,比较麻烦的是我们需要设置许多标记,要定位某一项内容,必须设置它的开始和结束标志。比如要取得网页上的文章标题,必须事先查看网页代码,查看出文章标题前边和后边的一些特征代码,通过这些特征代码,来截取文章的标题。
    下面我们来实际演示一下,假设要采集的文章地址为http://www.xxx.com/test.htm
    代码为:
    <html>
    <head>
    <meta http-equiv="Content-Language" content="zh-cn">
    <meta name="GENERATOR" content="Microsoft FrontPage 5.0">
    <meta name="ProgId" content="FrontPage.Editor.Document">
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>新建网页 1</title>
    </head>
    <body>
    <p align="center"><b>文章标题</b></p>
    <table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%" id="AutoNumber1">
    <tr><td width="60%">作者</td>
    <td width="40%">出处</td></tr>
    </table>
    <p><font size="2">这里是文章内容正文。</font></p>
    <a href='..new_pr.asp'>上一页</a> <a href='new_ne.asp'>下一页</a>
    </body>
    </html>
    第一步,我们用StrSource:= idHTTP1.Get(‘http://www.xxx.com/test.htm ’);将网页代码保存在strsource变量中。
    然后定义strTitle、strAuthor、strCopyFrom、strContent:
    strTitle:= GetStr(StrSource,’ <p align="center"><b>’,’ </b></p>’):
    strAuthor:= GetStr(StrSource,’ <tr><td width="60%">’,’ </td>’):
    strCopyFrom:= GetStr(StrSource,’ <td width="40%">’,’ </td></tr>’):
    strContent:= GetStr(StrSource,’ <p><font size="2">,’ </font></p>’):
    这样,就能把文章的标题、副题、作者、出处、日期、内容和分页分别存储在以上变量中。
    第二步,用循环的办法,打开下一页,并取得内容,加到strContent变量中。
    StrSource:= idHTTP1.Get(‘new_ne.asp’);
    strContent:= strContent +GetStr(StrSource,’ <p><font size="2">,’ </font></p>’):
    然后再判断有没有下一页,如果还有就接着取得下一页的内容。
    这样就完成了一个简单的截取过程。从以上的程序代码可以看到,我们使用的截取办法都是找截取内容的头部和尾部的,如果遇到这个头部和尾部有多个怎么办?似乎没办法,只会找到第一个,所以在找之前应该验证一下是不是只有一处有这个截取的内容的前后部。
    以上内容没有程序验证,仅供参考,如果认为有用可以试试。
    ///////////////////////////////////////
    用 Delphi 下载网页
    http://dev.csdn.net/develop/article/61/61609.shtm
    新建一个工程,放上一个TIdHTTP控件,一个TIdAntiFreeze控件,一个TProgressBar用于显示下载进度。最后放上一个TButton用于开始执行我们的命令。代码如下:
    procedure TForm1.Button2Click(Sender: TObject);
    var
    MyStream:TMemoryStream;
    begin
    IdAntiFreeze1.OnlyWhenIdle:=False;//设置使程序有反应.
    MyStream:=TMemoryStream.Create;
    try
    //下载我站点的一个ZIP文件
    IdHTTP1.Get('http://www.138soft.com/download/Mp3ToExe.zip',MyStream);
    except//INDY控件一般要使用这种try..except结构.
    Showmessage('网络出错!');
    MyStream.Free;
    Exit;
    end;
    MyStream.SaveToFile('c:Mp3ToExe.zip');
    MyStream.Free;
    Showmessage('OK');
    end;
    procedure TForm1.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
    const AWorkCountMax: Integer);
    begin
    ProgressBar1.Max:=AWorkCountMax;
    ProgressBar1.Min:=0;
    ProgressBar1.Position:=0;
    end;
    IdHTTP1的Get还有一种形式就是获取字符串:例如,上面的程序可以改写成:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    MyStr:String;
    begin
    IdAntiFreeze1.OnlyWhenIdle:=False;//设置使程序有反应.
    try
    MyStr:=IdHTTP1.Get('http://www.138soft.com/default.htm');
    except
    Showmessage('网络出错!');
    Exit;
    end;
    Showmessage(MyStr);
    end;

  • 相关阅读:
    2016百度之星资格赛 Problem B(大数+组合数)
    HDU 4380 Farmer Greedy(叉积和三角形知识的综合应用)
    C++ STL (备忘)
    【Linked List Cycle II】cpp
    【Linked List Cycle】cpp
    【Copy List with Random Pointer】cpp
    【Reverse Nodes in k-Group】cpp
    【Swap Nodes in Pairs】cpp
    【Remove Nth Node From End of List】cpp
    【Rotate List】cpp
  • 原文地址:https://www.cnblogs.com/blogpro/p/11346002.html
Copyright © 2011-2022 走看看