• Java抓取网页数据


    http://ayang1588.github.io/blog/2013/04/08/catchdata/

    最近处于离职状态,正赶清闲,开始着手自己的毕业设计,课题定的是JavaWeb购物平台,打算用SpringMVC+MyBatis实现,打算添加缓存服务器,用什么还没有想好,依赖用Maven管理,数据库用MySql,IDE就用Inetllij IDEA。


      购物平台业务都差不多,平时经常使用,业务大家都比较熟悉,我打算模拟当当网,所以昨天直接把数据库设计好,并建了起来,今天打算准备数据,可是product表和book表的字段稍微有点多,如果上网一个一个的摘录,肯定是不行事儿的,也不是coder做的事儿,要准备多的数据,又是重复的事儿,何不让计算机帮你干。所以打算用Java程序抓取现当当网的数据,提取自己想要的,并直接存入数据库。经过一下午的努力基本实现了功能,由于分类并不打算和当当网的分类一样那么多,所以实现了符合自己的半自动化数据抓取功能。可以实现输入当当网的类别(category_path),和起始结束页,自动填充数据库中对应对象。
      最开始用的正则匹配抓取内容,后来发现太麻烦了,正则左一斜杠右一斜杠的,又转义又拼接,一会就晕了,所以放弃了,改为像操作Dom树一样进行抓取,用到的开源包Jsoup文档),也支持像CSS过滤器一样过滤节点,很方便。但是这样并不支持获取js及ajax访问返回数据后的页面,但用htmlunit可以解决这个问题,htmlunit:传说中Java程序员的浏览器,具体使用不太难,就是模拟浏览器,设置好相关属性就可以开始访问了。这里有一篇淘宝关于定向抓取的介绍,大家可以看看(定向抓取漫谈)。
      以下是我访问当当数据的类(其余的就不贴了,数据库存储用的最原始的JDBC,没什么好说的,这个只是随便写个大概,够自己用了,其实完全可以拓展成通用的工具类,我就不封装了,本来就挺方便的,直接用也就够了),如果哪里有问题请记得及时给我留言

      1 public class Utils {
      2   
      3   // UrlVo类存放了3个url,列表图片url,详细信息中的图片url,和商品详细信息url
      4   // 再通过这三个url可以把所有数据读取出来并封装成对象,然后存入数据库。
      5   // 同时将所用到的图片下载到本地。
      6 
      7     /**
      8      * 从一个页面获取该页面商品详细信息的url链接和小图片的链接地址
      9      * @param url
     10      * @return
     11      * @throws
     12      */
     13     public static void getBookUrlFromPage(String url, List list) throws Exception{
     14         // timeout 0:不断请求  默认:2000毫秒超时
     15         Document document = Jsoup.connect(url).timeout(0).get();
     16         Elements node = document.select(".resultlist");
     17         Elements elements = node.get(0).child(0).children();
     18         for (Element item : elements) {
     19             UrlVO urlVO = new UrlVO();
     20             urlVO.setProductDetailUrl(item.child(1).child(0).child(0).child(0).attr("href"));
     21             urlVO.setSmallImageUrl(item.child(0).child(0).child(0).attr("src"));
     22             list.add(urlVO);
     23         }
     24     }
     25 
     26     /**
     27      * 根据url和页数获取商品详细url
     28      * @param url
     29      * @param startPage
     30      * @param endPage
     31      * @param list
     32      */
     33     public static void getBookUrlByUrlAndPageNum(String url, Integer startPage, Integer endPage, List list) {
     34         try {
     35             for(int i = startPage; i <= endPage; i++) {
     36                 String urlStr = url + i;
     37                 Utils.getBookUrlFromPage(urlStr, list);
     38             }
     39         } catch (Exception e) {
     40             e.printStackTrace();
     41         }
     42     }
     43 
     44     /**
     45      * 根据商品详细页面获取Product对象
     46      * @param url
     47      * @return
     48      */
     49     public static Product getProductFromUrl(String url) {
     50       //这里有些数据利用jsoup获取不到
     51         //我用的是htmlunit,设置setJavaScriptEnabled,setAjaxController等参数
     52         //具体代码就不贴了,大家可以自己试试
     53         //如有需要,求留言
     54         return null;
     55     }
     56 
     57     /**
     58      * 根据图片url和文件名保存图片
     59      * @param urlStr
     60      * @param filename
     61      */
     62     public static void saveImageByUrlAndName(String urlStr, String filename) throws Exception{
     63         // 构造URL
     64         URL url = new URL(urlStr);
     65         // 打开连接
     66         URLConnection con = url.openConnection();
     67         // 输入流
     68         InputStream is = con.getInputStream();
     69         // 1K的数据缓冲
     70         byte[] bs = new byte[1024];
     71         // 读取到的数据长度
     72         int len;
     73         // 输出的文件流
     74         OutputStream os = new FileOutputStream(filename);
     75         // 开始读取
     76         while ((len = is.read(bs)) != -1) {
     77             os.write(bs, 0, len);
     78         }
     79         os.flush();
     80         // 关闭连接
     81         os.close();
     82         is.close();
     83     }
     84 
     85     // 测试及调用
     86     public static void main(String[] args) {
     87         List<UrlVO> list = new ArrayList<UrlVO>();
     88         try {
     89             getBookUrlByUrlAndPageNum("http://category.dangdang.com/all/?category_path=01.03.38.00.00.00&page_index=", 1, 2, list);
     90 //            getBookUrlFromPage("http://category.dangdang.com/all/?category_path=01.03.38.00.00.00&page_index=2", list);
     91         } catch (Exception e) {
     92             e.printStackTrace();
     93         }
     94         System.out.println(list.size());
     95 
     96 //        保存图片
     97 //        String urlStr = "http://img32.ddimg.cn/28/35/23207212-1_l.jpg";
     98 //        try {
     99 //            saveImageByUrlAndName(urlStr, "1.jpg");
    100 //        } catch (Exception e) {
    101 //            e.printStackTrace();
    102 //        }
    103     }
    104 }
    【签名→→→】【****知其然知其所以然****】 工具只能帮助我们解决我们认识到的问题,解决不了我们都没理解的问题。 不能再把一切扔给框架、容器、工具! 首先理解你的业务逻辑,理解你要实现的功能, 然后搞清楚框架、容器、工具会帮助我们做什么。 只有理解了自己的业务逻辑,理解了自己的代码,理解了自己要用到的第三方代码, 才能真正完美地实现我们需要的功能!
  • 相关阅读:
    EXISTS 的使用
    bind()和 unbind()绑定解绑事件的使用
    前端代码
    LIKE CONCAT 连用
    客服工作台
    杂录
    vue
    咋乱杂乱的一些总结
    kotlin 很杂很杂
    group by 和 order by 的区别 + 理解过程
  • 原文地址:https://www.cnblogs.com/yaowukonga/p/3334512.html
Copyright © 2020-2023  润新知