java爬虫(爬新浪新闻) 如何从零开始

作者: 小鸡在路上 | 来源:发表于2017-12-28 19:49 被阅读278次

    爬虫

    通常搜索引擎处理的对象是互联网网页。首先面临的问题是:如何能够设计出高效的下载系统,以将如此海量的网页数据传送到本地,在本地形成互联网网页的镜像备份。网络爬虫即起此作用,它是搜索引擎系统中很关键也很基础的构件。
    爬虫:实际上就是通过相应的技术,抓取页面上特定的信息。

    网络爬虫

    当"蜘蛛"程序出现时,现代意义上的搜索引擎才初露端倪。它实际上是一种电脑"机器人"(Computer Robot),电脑"机器人"是指某个能以人类无法达到的速度不间断地执行某项任务的软件程序。由于专门用于检索信息的"机器人"程序就象蜘蛛一样在网络间爬来爬去,反反复复,不知疲倦。所以,搜索引擎的"机器人"程序就被称为"蜘蛛"程序。

    这种程序实际是利用html文档之间的链接关系,在Web上一个网页一个网页的爬取(crawl),将这些网页抓到系统来进行分析,并放入数据库中。第一个开发出"蜘蛛"程序的是Matthew Gray,他于1993年开发了World Wide Web Wanderer,它最初建立时是为了统计互联网上的服务器数量,到后来发展到能够捕获网址。现代搜索引擎的思路就来源于Wanderer,后来很多人在此基础上对蜘蛛程序进行了改进。

    运行流程图

    我们听得多的爬虫可能是python爬虫,因为以前没有接触过这门语言所以感觉爬虫是一门神秘的技术。今天看了一篇博客介绍的是利用Jsoup包也可以简便的进行爬虫开发,令我注意的是这是java的包,于是就有了想自己也做一个爬虫程序。这也就有了我今天的文章,这也是从小白到大白的一个过程,因为以前没有写过类似的,所以还是有点小成就感。闲话就说到这直接上代码。

    其实爬虫很简单,首先新建一个java工程。
    这是将抓取出来的信息保存到本地,提高效率

      /**
         * 
         * @Title: saveHtml
         * @Description: 将抓取过来的数据保存到本地或者json文件
         * @param 参数
         * @return void 返回类型
         * @author liangchu
         * @date 2017-12-28 下午12:23:05
         * @throws
         */
        public static void saveHtml(String url) {
            try {
                // 这是将首页的信息存入到一个html文件中 为了后面分析html文件里面的信息做铺垫
                File dest = new File("src/temp/reptile.html");
                // 接收字节输入流
                InputStream is;
                // 字节输出流
                FileOutputStream fos = new FileOutputStream(dest);
                URL temp = new URL(url);
                // 这个地方需要加入头部 避免大部分网站拒绝访问
                // 这个地方是容易忽略的地方所以要注意
                URLConnection uc = temp.openConnection();
                // 因为现在很大一部分网站都加入了反爬虫机制 这里加入这个头信息
                uc.addRequestProperty(
                        "User-Agent",
                        "Mozilla/5.0 "
                                + "(iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) "
                                + "AppleWebKit/533.17.9"
                                + " (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5");
                is = temp.openStream();
                // 为字节输入流加入缓冲
                BufferedInputStream bis = new BufferedInputStream(is);
                // 为字节输出流加入缓冲
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                int length;
                byte[] bytes = new byte[1024 * 20];
                while ((length = bis.read(bytes, 0, bytes.length)) != -1) {
                    fos.write(bytes, 0, length);
                }
                bos.close();
                fos.close();
                bis.close();
                is.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    分析本地的文件信息并将有用的信息提取出来 这一部分是比较耗时的

      /*
         * 解析本地的html文件获取对应的数据
         */
        public static void getLocalHtml(String path) {
            // 读取本地的html文件
            File file = new File(path);
            // 获取这个路径下的所有html文件
            File[] files = file.listFiles();
            List<New> news = new ArrayList<New>();
            HttpServletResponse response = null;
            HttpServletRequest request = null;
            int tmp=1;
            // 循环解析所有的html文件
            try {
                for (int i = 0; i < files.length; i++) {
    
                    // 首先先判断是不是文件
                    if (files[i].isFile()) {
                        // 获取文件名
                        String filename = files[i].getName();
                        // 开始解析文件
    
                        Document doc = Jsoup.parse(files[i], "UTF-8");
                        // 获取所有内容 获取新闻内容
                        Elements contents = doc.getElementsByClass("ConsTi");
                        for (Element element : contents) {
                            Elements e1 = element.getElementsByTag("a");
                            for (Element element2 : e1) {
                                // System.out.print(element2.attr("href"));
                                // 根据href获取新闻的详情信息
                                String newText = desGetUrl(element2.attr("href"));
                                // 获取新闻的标题
                                String newTitle = element2.text();                                                      
                                exportFile(newTitle, newText);
                                System.out.println("抓取成功。。。"+(tmp));
                                tmp++;
                                
                            }
                        }
                    }
    
                }
                
                //excelExport(news, response, request);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    根据url的信息获取这个url下的新闻详情信息

      /**
         * 
         * @Title: desGetUrl
         * @Description: 根据url获取连接地址的详情信息
         * @param @param url 参数
         * @return void 返回类型
         * @author liangchu
         * @date 2017-12-28 下午1:57:45
         * @throws
         */
        public static String desGetUrl(String url) {
            String newText="";
            try {
                Document doc = Jsoup
                        .connect(url)
                        .userAgent(
                                "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)")
                        .get();
                // System.out.println(doc);
                // 得到html下的所有东西
                //Element content = doc.getElementById("article");
                Elements contents = doc.getElementsByClass("article");
                if(contents != null && contents.size() >0){
                    Element content = contents.get(0);
                    newText = content.text();
                }
                //System.out.println(content);
                //return newText;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return newText;
        }
    

    将新闻信息写入文件中

      /*
         * 将新闻标题和内容写入文件
         */
        public static void exportFile(String title,String content){
            
            try {
                File file = new File("F:/replite/xinwen.txt");
                
                if (!file.getParentFile().exists()) {//判断路径是否存在,如果不存在,则创建上一级目录文件夹
                    file.getParentFile().mkdirs();
                }
                FileWriter fileWriter=new FileWriter(file, true); 
                fileWriter.write(title+"----------");
                fileWriter.write(content+"\r\n");
                fileWriter.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    

    主函数

      public static void main(String[] args) {
            String url = "http://news.sina.com.cn/hotnews/?q_kkhha";        
            // 解析本地html文件
            getLocalHtml("src/temp");       
        }
    
    数据.png

    总结

    刚开始没有做过之前觉得爬虫很神秘,自己真正做一遍之后发现其实也不过如此,其实很多东西都是一样,我们不要被眼前的困难所迷惑。当勇敢迈出这一步后,就会发现其实自己也可以这样。

    相关文章

      网友评论

      • 夜亦无影:老哥,List<New> news = new ArrayList<New>();这种写法没见过,请教下<New>我这个提示错误
        三千_1242:jsour.jar中的New?
        javax.enterprise.inject.New
        应该是的,谢谢
        三千_1242:List<New>中的New.java类中写了什么??
        小鸡在路上:@夜亦无影 new 是一个对象
      • 别怕_有我在:其实只要是有网络访问模块的编程语言,都是可以写爬虫程序的。
        小鸡在路上:@别怕_有我在 是的以前没有发现这个类 所以觉得麻烦

      本文标题:java爬虫(爬新浪新闻) 如何从零开始

      本文链接:https://www.haomeiwen.com/subject/nhovgxtx.html