zoukankan      html  css  js  c++  java
  • java网页数据抓取

    java网页数据抓取实例

     

    原文链接

    在很多行业中,要对行业数据进行分类汇总,及时分析行业数据,对于公司未来的发展,有很好的参照和横向对比。所以,在实际工作,我们可能要遇到数据采集这个概念,数据采集的最终目的就是要获得数据,提取有用的数据进行数据提取和数据分类汇总。

    很多人在第一次了解数据采集的时候,可能无从下手,尤其是作为一个新手,更是感觉很是茫然,所以,在这里分享一下自己的心得,希望和大家一起分享技术,如果有什么不足,还请大家指正。写出这篇目的,就是希望大家一起成长,我也相信技术之间没有高低,只有互补,只有分享,才能使彼此更加成长。

    在网页数据采集的时候,我们往往要经过这几个大的步骤:

    ①通过URL地址读取目标网页②获得网页源码③通过网页源码抽取我们要提取的目的数据④对数据进行格式转换,获得我们需要的数据。

    这是一个示意图,希望大家了解

    了解了基本流程,下来,我以一个案例具体实现如何提取我们需要的数据,对于数据提取可以用正则表达式进行提取,也可以用httpclient+jsoup进行提取,此处,暂且不讲解httpclient+jsou提取网页数据的做法,以后会对httpclient+jsoup进行专门的讲解,此处,先开始讲解如何用正则表达式对数据进行提取。

    我在这里找到一个网站:http://www.ic.NET.cn/userSite/publicQuote/quotes_list.PHP 我们要对里面的数据进行提取操作,我们要提取的最终结果是产品的型号、数量、报价、供应商,首先,我们看到这个网站整个页面预览

    其次我们看网页源码结构:

    上面源码可以很清楚的可以看到整个网页源码结构,下来我们就对整个网页数据进行提取

    复制代码
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class HTMLPageParser {
        public static void main(String[] args) throws Exception {
            //目的网页URL地址
            getURLInfo("http://www.ic.net.cn/userSite/publicQuote/quotes_list.php","utf-8");
        }
        public static List<Product> getURLInfo(String urlInfo,String charset) throws Exception {
            //读取目的网页URL地址,获取网页源码
            URL url = new URL(urlInfo);
            HttpURLConnection httpUrl = (HttpURLConnection)url.openConnection();
            InputStream is = httpUrl.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is,"utf-8"));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                //这里是对链接进行处理
                line = line.replaceAll("</?a[^>]*>", "");
                //这里是对样式进行处理
                line = line.replaceAll("<(\w+)[^>]*>", "<$1>");
                sb.append(line);
            }
            is.close();
            br.close();
            //获得网页源码
            return getDataStructure(sb.toString().trim());
        }
        static Pattern proInfo 
               = Pattern.compile("<div>(.*?)</div>\s*<div>(.*?)</div>\s*<div>(.*?)</div>\s*<div>(.*?)</div>\s*<div>(.*?)</div>", Pattern.DOTALL);
        private static List<Product> getDataStructure(String str) {
            //运用正则表达式对获取的网页源码进行数据匹配,提取我们所要的数据,在以后的过程中,我们可以采用httpclient+jsoup,
            //现在暂时运用正则表达式对数据进行抽取提取
            String[] info = str.split("</li>");
            List<Product> list = new ArrayList<Product>();
            for (String s : info) {
                Matcher m = proInfo.matcher(s);
                Product p = null;
                if (m.find()) {
                    p = new Product();
                    //设置产品型号
                    String[] ss = m.group(1).trim().replace(" ", "").split(">");
                    p.setProStyle(ss[1]);
                    //设置产品数量
                    p.setProAmount(m.group(2).trim().replace(" ", ""));
                    //设置产品报价
                    p.setProPrice(m.group(4).trim().replace(" ", ""));
                    //设置产品供应商
                    p.setProSupplier(m.group(5).trim().replace(" ", ""));
                    list.add(p);
                }
            }
            //这里对集合里面不是我们要提取的数据进行移除
            list.remove(0);
            for (int i = 0; i < list.size(); i++) {
                System.out.println("产品型号:"+list.get(i).getProStyle()+",产品数量:"+list.get(i).getProAmount()
                        +",产品报价:"+list.get(i).getProPrice()+",产品供应商:"+list.get(i).getProSupplier());
            }
            return list;
        }
    }
    class Product {
        private String proStyle;//产品型号
        private String proAmount;//产品数量
        private String proPrice;//产品报价
        private String proSupplier;//产品供应商
        public String getProStyle() {
            return proStyle;
        }
        public void setProStyle(String proStyle) {
            this.proStyle = proStyle;
        }
        public String getProSupplier() {
            return proSupplier;
        }
        public void setProSupplier(String proSupplier) {
            this.proSupplier = proSupplier;
        }
        
        public String getProAmount() {
            return proAmount;
        }
        public void setProAmount(String proAmount) {
            this.proAmount = proAmount;
        }
        public String getProPrice() {
            return proPrice;
        }
        public void setProPrice(String proPrice) {
            this.proPrice = proPrice;
        }
        public Product() {
            
        }
        @Override
        public String toString() {
            return "Product [proAmount=" + proAmount + ", proPrice=" + proPrice
                    + ", proStyle=" + proStyle + ", proSupplier=" + proSupplier
                    + "]";
        }
        
    }
    复制代码

    好了,运行上面程序,我们得到下面的数据,就是我们要获得的最终数据

    获得数据成功,这就是我们要获得最终的数据结果,最后我要说的是,此处这个网页算是比较简单的,而且,网页源码可以看到源数据,并且此方式是以get方式进行数据提交,真正采集的时候,有些网页结构比较复杂,可能会存在着源码里面没有我们所要提取的数据,关于这一点的解决方式,以后给大家进行介绍。还有,我在采集这个页面的时候,只是采集了当前页面的数据,它还有分页的数据,关于这个我此处不做讲解,只是提示一点,我们可以采用多线程对所有分页的当前数据进行采集,通过线程一个采集当前页面数据,一个进行翻页动作,就可以采集完所有数据。

    我们匹配的数据可能在项目实际开发中,要求我们对所提取的数据要进行数据储存,方便我们下一次进行数据的查询操作。

  • 相关阅读:
    股票数据可视化
    试下代码高亮
    【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第3节:Spark架构设计(2)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第3节:Spark架构设计(1)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第2节:Spark架构设计(2)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第2节:Spark架构设计(1)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第1节:为什么Spark是大数据必然的现在和未来?(2)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第1节:为什么Spark是大数据必然的现在和未来?(1)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第2章动手实战Scala第3小节:动手实战Scala函数式编程(2)
    【Spark亚太研究院系列丛书】Spark实战高手之路-第2章动手实战Scala第3小节:动手实战Scala函数式编程(1)
  • 原文地址:https://www.cnblogs.com/xing-nb/p/15135948.html
Copyright © 2011-2022 走看看