Android开发 - 抓取并解析网页数据(xml解析、html解析)

参考:android 开发--抓取网页解析网页内容的若干方法(网络爬虫)(正则表达式)

网页有两种格式,一种是xml另一种是html,目前似乎好像大部分都是html格式的,查看网页格式的方法是在浏览器中右键-->查看源码或者直接F12即可。

一、XML解析

1)DOM解析

DOM(Document Object Mode)是将XML文件的所有内容以文档树的方式存在内存中,通过节点以及节点之间的关系来解析XML文件。由于DOM操作会将整个XML文件存放在内存中,所以消耗内存大,较大的文档不采用这种方法解析。

2)SAX解析

SAX解析,逐行扫描XML文档,遇到标签时触发姐系处理器,采用事件处理的方式解析XML,在读取文档的同时即可对XML进行处理。可以解析超大XML,但是SAX解析只能读取XML中的数据,无法对数据进行增删改

3)PULL解析

PULL解析器是一个开源Java项目,既可用于Android应用也可用于JavaEE程序。Android中集成了PULL解析器,因此,Android中常用的就是PULL解析
此处提供一个xml地址:http://bbs.csdn.net/recommend_tech_topics.atom

使用案例:

此处使用pull解析的方式

需要解析的xml:

 <entry>
    <id>http://bbs.csdn.net/topics/392114349</id>
    <published>2017-03-08T15:51:57+08:00</published>
    <updated>2017-12-19T15:04:26+08:00</updated>
    <link rel="alternate" type="text/html" href="http://bbs.csdn.net/topics/392114349"/>
    <title>dubbo下如何使用hibernate的级联操作</title>
    <summary>dubbo下如何使用hibernate的级联操作</summary>
    <author>a461666405</author>
  </entry>
 <!--部分代码,具体点击上面链接 -->

根据xml内容分类创建实体类即可。

新建一个XMLSerivce工具类用来解析xml

public class XMLService {
    // 返回信息集合
    public static List<Bean> getNewsInfo(InputStream is) throws Exception {
        XmlPullParser parser = Xml.newPullParser(); // 获取Pull解析器
        parser.setInput(is, "utf-8");
        List<Bean> list = null;
        Bean bean = null;

        // 得到当前事件的类型
        int type = parser.getEventType();

        while (type != XmlPullParser.END_DOCUMENT) {

            switch (type) {
                // XML文档的开始START_DOCUMENT 例如:<?xml version="1.0" encoding="UTF-8"?> 0
                case XmlPullParser.START_DOCUMENT:
                    list = new ArrayList<>();
                    break;
                // XML文档节点开始START_TAG 例如:<entry> 2
                case XmlPullParser.START_TAG:
                    bean = new Bean();
                    if ("entry".equals(parser.getName())) {
                        Log.e("XML", "<ebtry>");


                    } else if ("id".equals(parser.getName())) {
                        String path = parser.nextText();
                        bean.setPath(path);
                        Log.e("XML", "path == " + path + "parse == " + parser.getName());

                    } else if ("published".equals(parser.getName())) {
                        String published = parser.nextText();
                        bean.setPublised(published);
                        Log.e("XML", "published == " + published + "parse == " + parser.getName());

                    } else if ("updated".equals(parser.getName())) {
                        String updtaed = parser.nextText();
                        bean.setUpdated(updtaed);
                        Log.e("XML", "updated == " + updtaed + "parse == " + parser.getName());

                    } else if ("title".equals(parser.getName())) {
                        String title = parser.nextText();
                        bean.setTitle(title);
                        Log.e("XML", "title == " + title + "parse == " + parser.getName());

                    } else if ("summary".equals(parser.getName())) {
                        String summary = parser.nextText();
                        bean.setUpdated(summary);
                        Log.e("XML", "summary == " + summary + "parse == " + parser.getName());

                    } else if ("author".equals(parser.getName())) {
                        String author = parser.nextText();
                        bean.setUpdated(author);
                        Log.e("XML", "author == " + author + "parse == " + parser.getName());

                    }
                    break;
                // XML文档的结束节点 如</entry> 3
                case XmlPullParser.END_TAG:

                    if ("entry".equals(parser.getName())) {
                        Log.e("XML", "解析xml一个节点完成" + parser.getName());

                        // 处理完一个entry标签
                        list.add(bean);
                        bean = null;
                    }
                    break;
            }
            type = parser.next(); // 解析下一个节点
        }
        return list;
    }
}

在Activity中,

private void pullParseXml(){

        final Message message = new Message();
        beanList = new ArrayList<>();

        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    URL url = new URL("http://bbs.csdn.net/recommend_tech_topics.atom");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setConnectTimeout(5000);
                    int code = conn.getResponseCode();
                    if (code == 200){
                        Log.e("XML","请求成功");
                        InputStream is = conn.getInputStream();
                        beanList = XMLService.getNewsInfo(is);
                        Log.e("XML",beanList.size()+ "");

                        // 成功获取数据 给主线程发消息
                        message.what = 3;
                        handler.sendMessage(message);
                    }

                } catch (Exception e) {
                    // 获取数据失败,给主线程发消息,处理数据
                    message.what = 4;
                    handler.sendMessage(message);

                    e.printStackTrace();
                }

            }
        }).start();

    }

得到的数据:


xml解析得到的数据

二、Html解析

数据源来自虎扑体育

虎扑体育源码

1)Jsoup

Jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

Jsoup的主要功能:

  1. 从一个 URL,文件或字符串中解析 HTML;
  2. 使用 DOM 或 CSS 选择器来查找、取出数据;
  3. 可操作 HTML 元素、属性、文本;

Jsoup的中文文档

------注释写在代码里-----

使用前需要导入Jsoup的jar包,复制jar包AndroidStudio中lib目录下并右键Add As Library。点击下载

使用案例

 private void getDataByJsoup(){

        final NewsInfo newsInfo = new NewsInfo();
        final Message message = new Message();
        newsList.add(newsInfo);

        // 开启一个新线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 网络加载HTML文档
                    Document doc = Jsoup.connect("https://voice.hupu.com/nba")
                            .timeout(5000) // 设置超时时间
                            .get(); // 使用GET方法访问URL
                    Elements elements = doc.select("div.list-hd");
                    for (Element element:elements){

                        String title = element.select("a").text(); // 新闻标题
                        String url = element.select("a").attr("href"); // 新闻内容链接
                        newsInfo.setTitle(title);
                        newsInfo.setNewsUrl(url);
                        Log.e("TAG","Jsoup ======>>" + title + url);
                    }
                    Elements elements1 = doc.select("div.otherInfo");
                    for (Element element: elements1){

                        String time = element.select("a").text(); // 时间
                        newsInfo.setNewsTime(time);
                        Log.e("TAG","Jsoup ======>>" + time );

                    }

                    message.what = 1;

                } catch (IOException e) {
                    message.what = 2;
                    e.printStackTrace();
                }
                handler.sendMessage(message);

            }
        }).start();

    }

获取的数据:

Jsoup获取的数据
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容