“捧腹网”页面结构分析

捧腹网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;}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108

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() {@Overridepublic void onRequestComplete(String result) {if (result == null) {return;}Document doc = Jsoup.parse(result);}});}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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(" ", "\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]"); //带有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;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/zuiwuyuan/article/details/52551809

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

  1. Android移动开发之【Android实战项目】记一次app开发过程!

    跟大家分享一下过程,经验(干货). 文章目录 一.开发环境选择: 1.AndoridStudio比Eclipse 2.AndroidStudio和Eclipse不同点总结 二.遇到的问题and经验分享 ...

  2. [ Android实战 ] java.lang.UnsatisfiedLinkError: No implementation found for xxx 问题解决

    [ Android实战 ] java.lang.UnsatisfiedLinkError: No implementation found for xxx 问题解决 背景 日志分析 解决问题 总结 尊 ...

  3. Android实战:手把手实现“捧腹网”APP(二)-----捧腹APP原型设计、实现框架选取...

    Android实战:手把手实现"捧腹网"APP(一)-–捧腹网网页分析.数据获取 Android实战:手把手实现"捧腹网"APP(二)-–捧腹APP原型设计.实 ...

  4. Android实战:手把手实现“捧腹网”APP(三)-----UI实现,逻辑实现

    APP页面实现 根据原型图,我们可以看出,UI分为两部分,底部Tab导航+上方列表显示. 所以此处,我们通过 FragmentTabHost+Fragment,来实现底部的导航页面,通过Recycle ...

  5. Android实战:手把手实现“捧腹网”APP(二)-----捧腹APP原型设计、实现框架选取

    APP原型设计 在APP的开发过程中,原型设计是必不可少的.用户界面原型必须在先启阶段的初期或在精化阶段一开始建立.整个系统(包括它的"实际"用户界面)的分析.设计和实施必须在原型 ...

  6. 【Android自定义View实战】之仿去哪儿网App图片按压显示指纹并缩放效果TouchFingerImageView

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/52986713 [DylanAndroid的csdn博客] 我们发现去哪儿网ap ...

  7. IT学习神器——慕课网App获App Store、Android应用市场重磅推荐

    作为国内首个IT学习类应用,慕课网App自上线以来持续获得苹果App Store推荐,是国内唯一一款被App Store推为榜首的教育类应用.慕课网在Android应用市场同样表现优异,受到各大知名应 ...

  8. Android实战项目: 视频资讯APP,源码在文章里免费分享

    文章目录 一.环境搭建 1.资源下载 2.视频地址 3.项目开发情况 二.项目展示 1.首页 2.资讯页面 3.个人中心 4.收藏页面实现 三.配置过程详解 1.导入Mysql数据库 2.Mongdb ...

  9. Android面试-Android性能优化和内存优化、APP启动速度一线大厂的实战案例解析

    一.Android 内存管理机制 二.优化内存的意义 三.避免内存泄漏 四.优化内存空间 五.图片管理模块的设计与实现 六.总结 深入探索Android内存优化 第一章.重识内存优化 第二章.常见工具 ...

最新文章

  1. 在网易有道做语音算法工程师是一种怎样的体验?
  2. 什么是时间导数(Time derivative)
  3. PAT甲级1083 List Grades:[C++题解]结构体、排序
  4. Qt Creator添加编译器
  5. 70后存款100万,有房有车无贷款,每月租金1.5万,可以退休吗?
  6. HALCON标定板制作、标准文件输出方法、算子讲解
  7. Kaggle官网免费课程:从Python到机器学习,4小时学完一门,48小时掌握数据科学...
  8. 文件不能自动求和_Excel求和公式函数的使用方法教程
  9. 颜色 透明度 算法_通过问责制和透明度减少算法偏差
  10. Trapcode Particular 5(合集·中英对照)
  11. dspscififo历程_DSP2812 SCI FIFO模式调试心得
  12. [转帖]VBS 教程
  13. 简洁的圆形时钟数字时钟+指针时钟(1+X Web前端开发初级 例题)
  14. 资深ios开发工程师收藏的iOS干货文章、大神的blog博客
  15. DBeaver设置Maven镜像仓库
  16. 珍藏绝版MTV全套 -《最动听的BEYOND
  17. 解决VS2022打开VS2015项目出现报错(warning : 无法找到 Visual Studio 2015 - Windows XP (v140_xp) 的生成工具……)
  18. 绘制二次贝塞尔曲线(二次贝兹曲线)等距线:让 IE 支持 canvas接口 isPointInPath
  19. 主成分分析(Principal Component Analysis)原理
  20. python编写仪表盘4

热门文章

  1. perl对文件和目录进行操作
  2. Dapr 助力应用架构的可持续性
  3. .NET6之MiniAPI(五):选项
  4. Polly的7种策略
  5. Azure App Service 如何在第一时间用上最新版 .NET Core
  6. Asp.Net Boilerplate微服务实战(二)架构解析
  7. 单点突破,击穿阈值,DevOps转型你需要这样做
  8. 《ASP.NET Core 微服务实战》-- 读书笔记(第3章)
  9. 【实战 Ids4】║ 给授权服务器加个锁——HTTPS配置
  10. WeihanLi.Npoi 支持 ShadowProperty 了