web3

用Java Socket获得网站的HTML代码,网络爬虫原理!  

2008-12-30 14:21:26|  分类: Java|字号 订阅

搜索引擎,他们的资料都是通过程序,去自动获取别的网站的HTML代码,然后进行分析,再从中获中一些有用的信息,分类,压缩,并存到数据库里面, 由于绝大部份HTML页面都有一些超链接,图片链接之类的信息,因些读取这些信息,就可以获得更多的网页地址,通过一些更深层次的算法,迭代周期性地去读 取所有的地址,就达到获取因特网信息的目的了,这样讲还是太抽象了,还是让我分步骤讲一下吧。

 

      1、首先,肯定是有起始的搜索地址的,比如我决定从http://www.hao123.com开 始搜索,因为它是网址分类网站嘛,里面包含了许多的网站链接地址,所以从这个网站开始的话,你抓取了第一个页面,并进行分析,就可以获得上百个别的网站的 链接地址了,将它们存起来先,待我搜我这个网站,我就一个一个地搜其它网站,并同理获得更多更多的网址,电脑干活不怕累,你别让它热到,它就会不日不夜地 帮你一个一个地搜下去了,如果你绝顶聪明,或许你像GOOGLE一样,财大气粗,请上N个有N年经验的工程师,不断地优化搜索与存取等的算法,你的搜索引 擎就强悍了,你再像GOOGLE一样买上百把万台服务器,租上几十座高楼,安装N台空调,将网络带宽扩展到NM,就让程序跑吧,跟着你就等别人来送钱给你 花了。

 

      2、像第一点那样按网址链搜索还不够,因为很多网址你根本链不过去,因为人家从来没在别的地方用过嘛,你没理由不让人家这样做的啊,又或者人家刚建的网 站,还没来得及在别人的论坛,或是别人的网站上到处贴他们的网址嘛,于是乎每个大的搜索网站都有这样的一个页面,让别人提交他们的网站,如果你的网站是新 的站的,我就建议你去提交一下,不然,或许,可能,一不小心你就要等上一年半载的,人家搜索引擎才好不容易从别的地方找到你的网站,呵呵,说笑的,只要你 网站能上网,他们肯定有办法得到你的网站的地址的,不然他们混什么混。

 

      3、好了,网站得到了,下一步就是将你们的信息都作一个缓存,以后别人搜索时,我就可以刷地一声将他们显示出来,不然的话,你的网站的带宽只有那么一K两 K,你想人家搜索引擎等你啊,不可能的,这样的话搜的人全跑了,不知道你们听说过百度的图片搜吧存了N多黄色图片没,以前特多,后来慢慢被找出来干掉了, 呵呵,就是因为百度把图片找出来,全存起来了,即使人家黄色网站被封了,百度就成了最大的黄色图片网站了,强吧!差点也被封,呵呵。不过缓存因特网的页面 可不是开玩笑的,你真想存上一半三分之一的,一来你要用最狠的无损压缩算法把它们压缩之后存进数据库,二来你又得买上N 台服务器,装上N个N大的硬盘,然后分存地将它们存起来,太复杂了,我说不明白也压根不懂它到底是怎么做到的,有兴趣你自己打电话问GOOGLE去。

 

      4、不讲了,我不是教书的,俺只是小程序员一个,敲键盘的,还是让我敲几行代码,给大家玩玩吧

看下面的程序

TestSocket.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;

/**
 *
 * @author Dao
 */
public class TestSocket
{

    public TestSocket()
    {
    }

    public static void main(String args[])
    {
        //你想获取代码的网站
        String strServer = "www.sina.com.cn";
        //起始页面,/为根页
        String strPage = "/";

        try
        {
            //设置端口,通常http端口不就是80罗,你在地址栏上没输就是这个值
            int port = 80;
            //用域名反向获得IP地址
            InetAddress addr = InetAddress.getByName(strServer);
            
            //建立一个Socket 
            Socket socket = new Socket(addr, port);

            //发送命令,无非就是在Socket发送流的基础上加多一些握手信息,详情请了解HTTP协议
            BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
            wr.write("GET " + strPage + " HTTP/1.0\r\n");
            wr.write("HOST:" + strServer + "\r\n");
            wr.write("Accept:*/*\r\n");
            wr.write("\r\n");
            wr.flush();
            
            //接收Socket返回的结果,并打印出来
            BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null)
            {
                System.out.println(line);
            }
            wr.close();
            rd.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

你运行一下,就会发现有一堆代码跑出来,除了全部的HTML代码,在前面还有一些Header信息,如下

HTTP/1.0 200 OK
Date:
 Tue, 09 Sep 2008 13:26:28 GMT
Server: Apache/2.0.63 (Unix)
Last-Modified: Tue, 09 Sep 2008 13:24:49 GMT
ETag: "5856b-4567675c7ca40"
Accept-Ranges: bytes
X-Powered-By: mod_xlayout_jh/0.0.1vhs.markII.remix
Cache-Control: max-age=60
Expires: Tue, 09 Sep 2008 13:27:28 GMT
Vary: Accept-Encoding
Content-Type: text/html
X-Cache: HIT from xa66-114.sina.com.cn
Age: 33
Content-Length: 374436
X-Cache: HIT from 236-49.D07072019.sina.com.cn
Via: 1.0 236-49.D07072019.sina.com.cn:80 (squid/2.6.STABLE13)
Connection: close

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--[30,59,1] published at 2008-09-09 21:24:49 from #194 by 2107-->
<html xmlns="http://www.w3.org/1999/xhtml">


...HTML代码略去

 

</html>

 

      其实那些Header信息也是非常有用的,你将它们进行分类,进行分析的话,还是可以发现非常多有用的信息的,具体怎么分析,还得看你具体要些什么,我也只是菜鸟一只,不会,别问我!

所以罗,我们得到了HTML代码了,下面就用你的聪明才智去做下一步的计划吧,我只会这些

不过获取代码的方式除了直接用Socket的InputStream/OutputStream之外,还有另外两种方式,分别是

1、URL类方式

public class TestSocket2

{

    public static void main(String args[])
    {

        try
        {
            URL url = new URL("http://www.sina.com");
            
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
            
            String s = "";
            
            StringBuffer sb = new StringBuffer();
            
            while ((s = br.readLine()) != null)
            {
                sb.append(s + "\r\n");
            }
            
            System.out.println(sb.toString());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }

    }

}

2、HttpUrlConnection方式

public class TestSocket3

{

    public static void main(String[] args)

    {

        try
        {
            URL urlmy = new URL("http://www.yosjob.com");
            
            HttpURLConnection con = (HttpURLConnection) urlmy.openConnection();
            
            con.setFollowRedirects(true);
            con.setInstanceFollowRedirects(true);
            con.connect();
            
            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            
            String s = "";
            
            StringBuffer sb = new StringBuffer();
            
            while ((s = br.readLine()) != null)
            {
                sb.append(s + "\r\n");
            }
            
            System.out.println(sb.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

}

不过这些的最终原理也是一个样,获取的内容也小有差异,具体用哪种还得根据实际需要,或你的爱好!


原文链接:http://blog.163.com/ccbobo_cat/blog/static/32099462200811302212655/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值