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

1,526 阅读4分钟
原文链接: blog.csdn.net

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

“捧腹网”页面结构分析

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

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

“捧腹网”网页源码分析

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

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

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

使用Jsoup解析网页

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

下面,我们通过Jsoup解析上图网页中的数据list-item 。
首先,我们需要首先获取网页源代码,jsoup提供了一个相当简单的方法,可以直接获取网页源代码,并把它转为Document对象。
Document doc = Jsoup.connect(“m.pengfu.com/index_1.htm…“).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();



                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 getNewJokelist(Document doc) {

        //class等于list-item的div标签
        Elements list_item_elements = doc.select("div.list-item")

        List jokeBeanList = new ArrayList<>()

        if (list_item_elements.size() > 0) {

            for (int i = 0

                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()
                        String lastTime = head_name_element.getElementsByClass("dp-i-b").first().text()

                        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(" ", "\n")
                            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]")

                    List tags = new ArrayList<>()

                    for (int j = 0

                        String tag = clearfixs.get(j) != null ? clearfixs.get(j).text() : ""
                        tags.add(tag)
                    }
                    jokeBean.setTags(tags)
                }

                jokeBeanList.add(jokeBean)
            }
        }

        return jokeBeanList

    }
}

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

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