ImageLoad+RollViewPage+Jsoup+WebView带你轻松实现抓取网页数据(附源码)

在Android开发中经常需要获取各种各样的数据,若服务器没有数据或者懒得去收集数据,这时候不妨采用Jsoup抓取各大网站的数据;若需要加载大量图片,想必也是个头疼的地方,这时候不妨使用universal-image-loader(图片加载框架);当然我们真正抓取的知识简单标题和URL链接,所有这时候还需要内置WebView用来显示正文。下面,我们就结合RollViewPage来如下功能。

这是要抓取的网页
这里写图片描述

这是效果:
这里写图片描述这里写图片描述


Jsoup的使用

要去爬别人的 HTML 标签的话,首先你肯定得有一定的 HTML 的基础知识吧。比如说常用的标签,标签的相关属性,这个就不多说了,有相关问题都可以在 www.w3school.com.cn 的网站解决一下。

准备

使用之前需要先导入Jsoup(源码有)

详解

目标Html代码:

<div id="da-slider" class="da-slider">

                <div class="da-slide">
                <h2>沟通表达 Tiny EMaG</h2>
                <p> 你和理想的学校之间,只差一场EMaG ~
面试礼仪   ||   沟通表达
问答技巧   ||   演讲训练
社交技能   ||   思维逻辑
……
表达一门永无止境的艺术</p>
                                    <a href="http://www.educubeglobal.com/master/get_notice_by_id/55" target="_blank" class="da-link">More</a>

                <div class="da-img"> <img src="/application/script/kindeditor-4.1.4/attached/image/20150430/20150430145125_26612.jpg" alt="EmaG" /></div>
                </div>

                <div class="da-slide">
                <h2>台湾深度探访营~新一代背包客</h2>
                <p> 学立方新一代背包客,走进台湾,开创个人亲身体验的“我学我立,方成长”的一种超越时空、文化与科技的学习方法,走一段非比寻常的闽台文化交流之旅。</p>
                                    <a href="http://www.educubeglobal.com/master/teenager" target="_blank" class="da-link">More</a>

                <div class="da-img"> <img src="/application/script/kindeditor-4.1.4/attached/image/20140527/20140527170608_48705.jpg" alt="EmaG" /></div>
                </div>

                <div class="da-slide">
                <h2>学立方百英计划</h2>
                <p> 百炼成钢,英才辈出!学立方2014素质拓展夏令营,在这里,我们学习有方法,成长有素质,生活有文化,在快乐中为下学年的学习创造健康扎实的基础。</p>
                                    <a href="http://www.educubeglobal.com/master/teenager" target="_blank" class="da-link">More</a>

                <div class="da-img"> <img src="/application/script/kindeditor-4.1.4/attached/image/20140528/20140528110147_89047.jpg" alt="EmaG" /></div>
                </div>

                <div class="da-slide">
                <h2>台湾夏令营~新一代背包客4.0</h2>
                <p> 从领袖训练到英语学习、从校园体验到田园知趣、 从夜市到故宫、从人性到文化、从台北101到南投日月潭, 多方促进海峡两岸青少年交流,增进双方友谊,深入了解台湾, 加入学立方夏令营,您将有难忘的学习交流经验与美好的回忆。</p>
                                    <a href="http://www.educubeglobal.com/CSPDM/" target="_blank" class="da-link">了解更多</a>

                <div class="da-img"> <img src="/application/script/kindeditor-4.1.4/attached/image/20130619/20130619154828_13834.png" alt="EmaG" /></div>
                </div>

                <div class="da-slide">
                <h2>学立方素质教育网</h2>
                <p> 素质教育的推广与实践,是学立方教育从人本出发的服务核心,旨在锻造在学儿少青年与在职专业人员“双语视野、信息应用、体能体魄、人文通识、沟通领导、社会网络、问题解决与思辨决策”等八项素质能力,采用曾章瑞教授所创建的EMaG模式积极发展。</p>
                                    <a href="http://www.educubeglobal.com/CSPDM" target="_blank" class="da-link">进入网站</a>

                <div class="da-img"> <img src="/application/script/kindeditor-4.1.4/attached/image/20131127/20131127173239_20069.jpg" alt="EmaG" /></div>
                </div>

                <div class="da-slide">
                <h2>学立方推出“新一代托管课程”</h2>
                <p> 1、辅导并确保完成作业——每天进步一点点! 2、完成作业后转化为趣味休闲: (1)3D影片(动画)展播与互动学习——不一样的学习有不一样的成长。 (2)Asaka姐姐讲故事——精彩持续,激发想象力。 (3)素质训练、益智游戏——智力和素质的同步成长。</p>

                <div class="da-img"> <img src="/application/script/kindeditor-4.1.4/attached/image/20130620/20130620163946_67744.jpg" alt="EmaG" /></div>
                </div>
                      <div class="da-arrows"> <span class="da-arrows-prev"></span><span class="da-arrows-next"></span> </div>
    </div>

解析Html代码:
(1)审查网页元素后发现,我们要的内容在上面的目标HTML代码中,在整个网页中是在 class=”da-slider” id=”da-slider”
(2)标题如“沟通表达 Tiny EMaG<”都在“h2”标签中
(3)需要的图片链接都在 “img”标签中
(4)需要的网页链接都在 “a”标签中,注意这边是在“a”中的“href”
好了,标题、图片链接、网页链接都已经到手,我们可以抓取获取

try {
            //创建一个Document对象获取网页内容
           doc = Jsoup.connect("http://www.educubeglobal.com/").get();
           //通过Elements 对象获取da-slider下的内容
           Elements elements1 = doc.select("[class=da-slider][id=da-slider]");
           //获取所有<h2>标签的内容
           Elements elements2 = elements1.select("h2");
           //获取所有<img>标签的内容
           Elements elements3 = elements1.select("img");
           //获取所有<a>标签的内容
           Elements elements4 = elements1.select("a");
           for(int i=0;i<elements2.size();i++){
           //将获取的内容全部放在 m 中
           Map<String,String> m=new HashMap<>();
           m.put("title",elements2.get(i).text());
                    m.put("img","http://www.educubeglobal.com"+elements3.get(i).attr("src"));
               m.put("url",elements4.get(i).attr("href"));
               map.add(m);
             }

  } catch (Exception e) {
         // TODO Auto-generated catch block
          e.printStackTrace();
         }
          return map ;
          //return test();
    }

来看一下MainActivity的代码:

package test.quxing.com.getnews;

import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import com.jude.rollviewpager.OnItemClickListener;
import com.jude.rollviewpager.RollPagerView;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    private RollPagerView rollPagerView;
    private ArrayList<String> imageUrlList ;
    private ArrayList<String> linkUrlArray;
    private ArrayList<String> titleList ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            ProgressAsyncTask asyncTask=new ProgressAsyncTask();
            asyncTask.execute(10000);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        rollPagerView = (RollPagerView) findViewById(R.id.view_rollpager);

    }

    public void getData(List<Map<String, String>> map) {
        imageUrlList = new ArrayList<>();
        linkUrlArray= new ArrayList<>();
        titleList = new ArrayList<>();

        for (int i=0;i<map.size();i++){
            imageUrlList.add(map.get(i).get("img"));
            linkUrlArray.add(map.get(i).get("url"));
            titleList.add(map.get(i).get("title"));
        }

        rollPagerView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                String url = linkUrlArray.get(position);
                if(url==null){
                    Toast.makeText(MainActivity.this, "暂无该链接",
                            Toast.LENGTH_SHORT).show();
                }
                else {
                    Bundle bundle = new Bundle();

                    bundle.putString("url", url);
                    Intent intent = new Intent(MainActivity.this, BaseWebActivity.class);
                    intent.putExtras(bundle);
                    startActivity(intent);
                }

            }
        });
        rollPagerView.setAdapter(new RollViewAdapter(MainActivity.this,rollPagerView,imageUrlList,titleList));

        // initBanner(imageUrlList,linkUrlArray,titleList);
    }

    class ProgressAsyncTask extends AsyncTask<Integer, Integer,  List<Map<String,String>>> {

        private List<Map<String,String>> map;
        public ProgressAsyncTask() {
            super();
            map=new ArrayList<>();
        }

        @Override
        protected  List<Map<String,String>> doInBackground(Integer... params) {
            Document doc = null;

            try {
                doc = Jsoup.connect("http://www.educubeglobal.com/").get();
                Elements elements1 = doc.select("[class=da-slider][id=da-slider]");
                Elements elements2 = elements1.select("h2");
                Elements elements3 = elements1.select("img");
                Elements elements4 = elements1.select("a");
                for(int i=0;i<elements2.size();i++){
                    Map<String,String> m=new HashMap<>();
                    m.put("title",elements2.get(i).text());
                    m.put("img","http://www.educubeglobal.com"+elements3.get(i).attr("src"));
                    m.put("url",elements4.get(i).attr("href"));
                    map.add(m);
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return map ;
            //return test();
        }

        @Override
        protected void onPostExecute( List<Map<String,String>> result) {

            getData(result);

        }

        // 该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置
        @Override
        protected void onPreExecute() {

        }
        @Override
        protected void onProgressUpdate(Integer... values) {

        }
    }
}

上面代码先在onCreate中执行 声明并执行ProgressAsyncTask , 获取到网页内容后执行getData并对rollPagerView进行适配。下面来介绍rollPagerView的使用

rollPagerView

准备

导入rollPagerView的jar包,并添加依赖:

compile 'com.jude:rollviewpager:1.4.6'

详解

先来看下布局:

<com.jude.rollviewpager.RollPagerView
        android:layout_width="match_parent"
        android:layout_height="180dp"
        android:background="@drawable/bg_user_card"
        android:layout_margin="0dp"
        android:orientation="vertical"
        android:id="@+id/view_rollpager"
        app:rollviewpager_play_delay="3000" >

    </com.jude.rollviewpager.RollPagerView>

我们再来看下rollPagerView的适配器代码:

package test.quxing.com.getnews;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.jude.rollviewpager.RollPagerView;
import com.jude.rollviewpager.adapter.LoopPagerAdapter;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import java.util.ArrayList;
import java.util.List;
public class RollViewAdapter extends LoopPagerAdapter {
    private List<String> imageIdList;//图片链接
    private List<String> titleList;//标题
    private DisplayImageOptions options;
    private Context context;
    private ImageLoader imageLoader;

    public RollViewAdapter(Context context, RollPagerView viewPager, ArrayList<String> imageUrlList, ArrayList<String> titleList) {
        super(viewPager);
        this.context = context;
        this.imageIdList = imageUrlList;
        this.titleList = titleList;

        // 初始化imageLoader 否则会报错
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(ImageLoaderConfiguration.createDefault(context));
        options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.ic_launcher) // 设置图片下载期间显示的图片
                .showImageForEmptyUri(R.drawable.ic_launcher) // 设置图片Uri为空或是错误的时候显示的图片
                .showImageOnFail(R.drawable.ic_launcher) // 设置图片加载或解码过程中发生错误显示的图片
                .cacheInMemory(true) // 设置下载的图片是否缓存在内存中
                .cacheOnDisc(true) // 设置下载的图片是否缓存在SD卡中
                .build();
    }

    @Override
    public View getView(ViewGroup container, int position) {

        View view = LayoutInflater.from(context).inflate(R.layout.item_viewpage, null);
        ImageView imageView = (ImageView)view.findViewById(R.id.image);

        TextView page = (TextView)view.findViewById(R.id.page);
        TextView title = (TextView)view.findViewById(R.id.title);

        imageLoader.displayImage(
                (String) this.imageIdList.get(position),
                imageView, options);
        page.setText(position+1+"/"+imageIdList.size());
        title.setText(titleList.get(position));
        return view;
    }

    @Override
    public int getRealCount() {
        return imageIdList.size();
    }
}

是不是和普通的listview适配器很相似,这里就不再多说了。我们再来看下上面代码中的ImageLoader和DisplayImageOptions,这就是我们接下来要介绍的universal-image-loader图片加载框架。

universal-image-loader图片加载框架

相信大家平时做Android应用的时候,多少会接触到异步加载图片,或者加载大量图片的问题,而加载图片我们常常会遇到许多的问题,比如说图片的错乱,OOM等问题,对于新手来说,这些问题解决起来会比较吃力,所以就有很多的开源图片加载框架应运而生,比较著名的就是Universal-Image-Loader。本文只介绍Universal-Image-Loader的简单使用,笔者觉得这篇介绍得很不错,感兴趣的朋友可以去了解看看。

准备

导入Universal-Image-Loader的jar包

详解

首先创建ImageLoader对象并对其初始化:

       imageLoader = ImageLoader.getInstance();

ImageLoaderConfiguration是图片加载器ImageLoader的配置参数,这里是直接使用了createDefault()方法创建一个默认的ImageLoaderConfiguration。然后调用ImageLoader的init()方法将ImageLoaderConfiguration参数传递进去

imageLoader.init(ImageLoaderConfiguration.createDefault(context));

我们使用DisplayImageOptions来配置显示图片的一些选项,这里添加了将图片缓存到内存中已经缓存图片到文件系统中,这样我们就不用担心每次都从网络中去加载图片了,设置如下(代码已给出注释):

options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.ic_launcher) // 设置图片下载期间显示的图片
                .showImageForEmptyUri(R.drawable.ic_launcher) // 设置图片Uri为空或是错误的时候显示的图片
                .showImageOnFail(R.drawable.ic_launcher) // 设置图片加载或解码过程中发生错误显示的图片
                .cacheInMemory(true) // 设置下载的图片是否缓存在内存中
                .cacheOnDisc(true) // 设置下载的图片是否缓存在SD卡中
                .build();

好了,完成以上设置后就可以开始加载图片了,加载代码如下:

imageLoader.displayImage((String) this.imageIdList.get(position),imageView, options);

  • (String) this.imageIdList.get(position)为我们要加载的图片链接
  • imageView为我们要显示的控件的实例
  • options即为我们刚刚配置显示图片的一些选项
  • 好了,ImageLoader就简单介绍到这边。接下来我们在回到MainActivity,我们为rollPagerView设置的点击事件中:

            String url = linkUrlArray.get(position);
            if(url==null){
                Toast.makeText(MainActivity.this, "暂无该链接",Toast.LENGTH_SHORT).show();
           }
            else {
                Bundle bundle = new Bundle();
                bundle.putString("url", url);
                Intent intent = new Intent(MainActivity.this, BaseWebActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
           }
    

    其中的BaseWebActivity就是接下来要介绍的WebView。

    WebView

    详解

    来看一下布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
        <WebView
            android:id="@+id/wv_internet"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:fadeScrollbars="true"
            android:scrollbarStyle="insideOverlay" />
    
    </LinearLayout>

    接下来看下对于的BaseWebActivity(代码已经给出详细注释):

    package test.quxing.com.getnews;
    
    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.KeyEvent;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.Window;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    
    
    /**
     * @Description:WebView界面,带自定义进度条显示
     * @author http://blog.csdn.net/finddreams
     */ 
    public class BaseWebActivity extends AppCompatActivity {
    
        private WebView webview;
        private ProgressDialog pd;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_baseweb);
    
            pd=new ProgressDialog(this);
            pd.setMessage("正在加载...");
    
            Intent intent = getIntent();
            Bundle bundle = intent.getExtras();
            String url = bundle.getString("url");
    
            go(url);
            //webview的简单设置
    
        }
    
        public void go(String url){
            webview=(WebView) findViewById(R.id.wv_internet);
            webview.loadUrl(url);//加载网页
            WebSettings websettings=webview.getSettings();
            websettings.setUseWideViewPort(true);//将图片调整到适合webview的大小
            websettings.setLoadWithOverviewMode(true);// 缩放至屏幕的大小
            websettings.setSupportZoom(true);//支持缩放
            websettings.setBuiltInZoomControls(true);//设置支持缩放
            webview.setWebViewClient(new WebViewClient(){
    
                /**
                 * //这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
                 *
                 */
                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    pd.show();
                }
    
                /**
                 * //在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关闭loading 条,切换程序动作。
    
                 */
                @Override
                public void onPageFinished(WebView view, String url) {
                    pd.dismiss();
                }
            });
        }
        //后退键
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if(keyCode== KeyEvent.KEYCODE_BACK&&webview.canGoBack()){
                webview.goBack();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
        //菜单键
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            menu.add(0, 0, 0, "刷新");
            menu.add(0, 0, 1, "后退");
            menu.add(0, 0, 2, "前进");
            return super.onCreateOptionsMenu(menu);
        }
        //菜单点击事件
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getOrder()) {
                case 0:
                    webview.reload();
                    break;
                case 1:
                    if(webview.canGoBack()){
                        webview.goBack();
                    }
                    break;
                case 2:
                    if(webview.canGoForward()){
                        webview.goForward();
                    }
                    break;
            }
            return super.onOptionsItemSelected(item);
        }
    
    }
    

  • WebSettings是用于设置WebView的页面状态
  • WebViewClient 回调对应的方法改变网页内容的呈现方式
  • onKeyDown的作用是按返回键时, 不退出程序而是返回上一浏览页面
  • WebView 加载界面主要调用三个方法:LoadUrl、LoadData、LoadDataWithBaseURL.(这里使用的是LoadUrl)
    更多关于WebView的使用可以参考这篇博客

  • 好啦,源码地址:https://github.com/HeyGoing/GetNews

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值