• Android实战:手把手实现“捧腹网”APP(一)-----捧腹网网页分析、数据获取


    Android实战:手把手实现“捧腹网”APP(一)—–捧腹网网页分析、数据获取
    Android实战:手把手实现“捧腹网”APP(二)—–捧腹APP原型设计、实现框架选取
    Android实战:手把手实现“捧腹网”APP(三)—–UI实现,逻辑实现


    “捧腹网”页面结构分析

    捧腹网M站地址: http://m.pengfu.com/

    捧腹网M站部分截图:
    这里写图片描述
    这里写图片描述
    从截图中(可以直接去网站看下),我们可以看出,该网站相对简单,一共分为四个模块:最新笑话、捧腹段子、趣图、神回复。 然后页面的显示形式有两种,一是单纯的文字(段子),二是单纯的图片(趣图)。其中趣图又分为静态图片和动态图片(gif图),且趣图的显示比段子多了“标签”。

    “捧腹网”网页源码分析

    在网页中点击右键,点击弹出菜单中的“查看网页代码”,就可以查看到当前网页的源代码。查看源代码,我们可以看出,每一个笑话,都是一个list-item。我截取部分代码,给大家略作分析。
    这里写图片描述
    这里写图片描述
    这里写图片描述
    我在上图中已经进行了标注,整个捧腹网的数据大体也就这三部分:段子、静态图、动态图。其中,每个list-item中的数据包括:用户头像、用户昵称、笑话的标题、笑话内容(段子内容、静态图、动态图),标签。

    “捧腹网”数据列表请求URL分析

    最新笑话列表:http://m.pengfu.com/index_num.html, 其中num为第几页。
    捧腹段子列表:http://m.pengfu.com/xiaohua_num.html , 其中num为第几页。
    趣图列表:http://m.pengfu.com/qutu_num.html , 其中num为第几页。
    神回复列表:http://m.pengfu.com/shen_num.html , 其中num为第几页。

    使用Jsoup解析网页

    Jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
    关于如何使用Jsoup并不是本章重点,它并不难使用,具体可以参考jsoup开发指南http://www.open-open.com/jsoup/ ,相信你浏览一遍就知道它的使用方式了。

    下面,我们通过Jsoup解析上图网页中的数据list-item 。
    首先,我们需要首先获取网页源代码,jsoup提供了一个相当简单的方法,可以直接获取网页源代码,并把它转为Document对象。
    Document doc = Jsoup.connect(“http://m.pengfu.com/index_1.html“).get();
    当然,你也可以自己通过httpurlconnection获取到网页的数据流,然后通过 Document doc = Jsoup.parse(result);方法把它转为Document对象。

    在实际开发中,我们需要用过异步任务,获取、解析网络数据,所以,在这里,我通过httpurlconnection来获取网页源码。

    1.封装HTTP请求工具类

    package com.lnyp.joke.http;
    
    import java.io.BufferedReader;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    /**
     * Http请求的工具类
     *
     */
    public class HttpUtils {
    
        private static final int TIMEOUT_IN_MILLIONS = 10000;
    
        public interface CallBack {
            void onRequestComplete(String result);
        }
    
        /**
         * 异步的Get请求
         *
         * @param urlStr
         * @param callBack
         */
        public static void doGetAsyn(final String urlStr, final CallBack callBack) {
            new Thread() {
                public void run() {
                    try {
                        String result = doGet(urlStr);
                        if (callBack != null) {
                            callBack.onRequestComplete(result);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                }
    
                ;
            }.start();
        }
        /**
         * Get请求,获得返回数据
         *
         * @param urlStr
         * @return
         * @throws Exception
         */
        public static String doGet(String urlStr) {
            URL url = null;
            HttpURLConnection conn = null;
            InputStream is = null;
            ByteArrayOutputStream baos = null;
            try {
                url = new URL(urlStr);
                conn = (HttpURLConnection) url.openConnection();
    
                conn.setReadTimeout(TIMEOUT_IN_MILLIONS);
                conn.setConnectTimeout(TIMEOUT_IN_MILLIONS);
                conn.setRequestMethod("GET");
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("User-Agent", "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52");
                if (conn.getResponseCode() == 200) {
                    is = conn.getInputStream();
                    baos = new ByteArrayOutputStream();
                    int len = -1;
                    byte[] buf = new byte[128];
    
                    while ((len = is.read(buf)) != -1) {
                        baos.write(buf, 0, len);
                    }
                    baos.flush();
    
    //                System.out.print("str : " + baos.toString());
    
                    return baos.toString();
                } else {
                    throw new RuntimeException(" responseCode is not 200 ... ");
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (is != null)
                        is.close();
                } catch (IOException e) {
                }
                try {
                    if (baos != null)
                        baos.close();
                } catch (IOException e) {
                }
                conn.disconnect();
            }
    
            return null;
    
        }
    
    }
    

    2.查询网页源码,转化为Document对象。

    private void qryJokes() {
    
            final String url = "http://m.pengfu.com/index_1.html";
            System.out.println(url);
    
            HttpUtils.doGetAsyn(url, new HttpUtils.CallBack() {
    
                @Override
                public void onRequestComplete(String result) {
    
                    if (result == null) {
                        return;
                    }
    
                    Document doc = Jsoup.parse(result);
                }
            });
    
        }
    

    3.通过Jsoup解析网页源码,封装列表数据

    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 笑话工具类
     */
    public class JokeUtil {
    
        public List<JokeBean> getNewJokelist(Document doc) {
    
            //class等于list-item的div标签
            Elements list_item_elements = doc.select("div.list-item");
    
            List<JokeBean> jokeBeanList = new ArrayList<>();
    
            if (list_item_elements.size() > 0) {
    
                for (int i = 0; i < list_item_elements.size(); i++) {
    
                    JokeBean jokeBean = new JokeBean();
    
    
                    Element list_item_element = list_item_elements.get(i);
    
                    Elements head_name_elements = list_item_element.select("div.head-name");
    
                    if (head_name_elements.size() > 0) {
                        Element head_name_element = head_name_elements.first();
                        if (head_name_element != null) {
                            String userAvatar = head_name_element.select("img").first().attr("src");
                            String userName = head_name_element.select("a[href]").get(1).text(); //带有href属性的a元素
                            String lastTime = head_name_element.getElementsByClass("dp-i-b").first().text(); //带有href属性的a元素
    
                            String shareUrl = head_name_element.select("a[href]").get(1).attr("href");
    
                            jokeBean.setUserAvatar(userAvatar);
                            jokeBean.setUserName(userName);
                            jokeBean.setLastTime(lastTime);
    
                            jokeBean.setShareUrl(shareUrl);
                        }
                    }
    
                    Element con_img_elements = list_item_element.select("div").get(2);
                    if (con_img_elements != null) {
                        if (con_img_elements.select("img") != null) {
    
                            Element img_element = con_img_elements.select("img").first();
    
                            JokeBean.DataBean dataBean = new JokeBean.DataBean();
    
                            if (img_element != null) {
                                String showImg = img_element.attr("src");
                                String gifsrcImg = img_element.attr("gifsrc");
                                String width = img_element.attr("width");
                                String height = img_element.attr("height");
    
                                dataBean.setShowImg(showImg);
                                dataBean.setGifsrcImg(gifsrcImg);
                                dataBean.setWidth(width);
                                dataBean.setHeight(height);
    
                            } else {
                                String content = con_img_elements.text().replaceAll(" ", "
    ");
                                dataBean.setContent(content);
                            }
    
                            jokeBean.setDataBean(dataBean);
    
                        }
                    }
    
    
                    Element tagwrap_clearfix_elements = list_item_element.select("div").get(3);
                    if (tagwrap_clearfix_elements != null) {
    
                        Elements clearfixs = tagwrap_clearfix_elements.select("a[href]"); //带有href属性的a元素
    
                        List<String> tags = new ArrayList<>();
    
                        for (int j = 0; j < clearfixs.size(); j++) {
    
                            String tag = clearfixs.get(j) != null ? clearfixs.get(j).text() : "";
                            tags.add(tag);
                        }
                        jokeBean.setTags(tags);
                    }
    
                    jokeBeanList.add(jokeBean);
                }
            }
    
            return jokeBeanList;
    
        }
    }

    本章小结:
    本章主要介绍了如何通过解析网页源码获取网页中的数据,其实不难,静下心来,一点点分析,利用jsoup便可以轻而易举的拿到我们想要的数据。
    获取到了数据之后,接下我们便可以设计、实现“捧腹”APP。
    更多内容,下面会继续详解。

    如果你迫不及待的想看源码,请前往https://github.com/zuiwuyuan/Joke查看。谢谢大家的支持。

  • 相关阅读:
    深入理解Java内存(图解堆栈)
    java堆栈区别
    Java之堆栈的区别
    【微信小程序】获取轮播图当前图片下标、滑动展示对应的位数、点击位数展示对应图片
    【微信小程序】转载:微信小程序实战篇-下拉刷新与加载更多
    【微信小程序】转载:微信小程序之购物车功能
    【微信小程序】loading标签使用,可自定义时长
    【微信小程序】日历插件,适用于酒店订房类小程序
    【微信小程序】微信小程序wx.previewImage预览图片
    【微信小程序】小程序和公众号 退款功能教程(含申请退款和退款回调,退款回调地址在商户后台配置或者代码自定义)
  • 原文地址:https://www.cnblogs.com/hehe520/p/6329930.html
走看看 - 开发者的网上家园