Jsoup抓取网页数据完成一个简易的Android新闻APP
前言:作为一个篮球迷,每天必刷NBA新闻。用了那么多新闻APP,就想自己能不能也做个简易的新闻APP。于是便使用Jsoup抓取了虎扑NBA新闻的数据,完成了一个简易的新闻APP。虽然没什么技术含量,但还是写一下过程,满足一下菜鸟小小的成就感。
关于Jsoup
- jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。
- Jsoup的中文文档:点击这里
- Jsoup的jar包下载地址:点击这里
分析与思路
虎扑NBA新闻网页的新闻列表如图所示:
我们所要做的便是获取图中每条新闻的新闻标题、新闻概要、新闻时间与来源以及新闻的链接地址这四个信息,而后用一个实体类News封装上述四个数据,再布局到ListView上。点击ListView的每个子项,便将该子项所显示的新闻的链接地址用一个WebView显示出来,便大功告成。效果如图:
具体实现过程
1.在AndroidStudio新建工程JsoupTest,而后将Jsoup的jar包【下载地址】拷到项目的libs下,然后右键Add As Library...
2.修改activity_main.xml的布局,简单加入一个ListView,并设置一下Listview的每两个子项间的间隔的距离和颜色
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/news_lv"android:dividerHeight="7dp"android:divider="#dcdcdc"></ListView> </LinearLayout>
3.建立一个实体类News来封装我们等会要从网页中获取的新闻的标题、概要、时间与来源、链接地址这四个数据。很简单,用四个变量分别代表上述四个数据,并建立相应的构造方法以及四个变量的get与set方法。
public class News {private String newsTitle; //新闻标题private String newsUrl; //新闻链接地址private String desc; //新闻概要private String newsTime; //新闻时间与来源public News(String newsTitle, String newsUrl, String desc, String newsTime) {this.newsTitle = newsTitle;this.newsUrl = newsUrl;this.desc = desc;this.newsTime = newsTime;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public String getNewsTime() {return newsTime;}public void setNewsTime(String newsTime) {this.newsTime = newsTime;}public String getNewsTitle() {return newsTitle;}public void setNewsTitle(String newsTitle) {this.newsTitle = newsTitle;}public String getNewsUrl() {return newsUrl;}public void setNewsUrl(String newsUrl) {this.newsUrl = newsUrl;}
}
4.最重要的一步:利用Jsoup获取虎扑NBA新闻网页的数据,并封装到News实体类中。就简单概述下实现方法
- 查看虎扑NBA新闻的网页源代码。谷歌浏览器,右键-查看网页源代码。其他浏览器应该都差不多。
我们直接查看显示新闻列表的这部分代码,我们截图下两条新闻的代码来进行分析- 新闻1源代码:
- 新闻2源代码:
- 新闻1源代码:
分析上图两条新闻的源代码,找到我们所打算要获取的新闻的标题、概要、时间与来源、链接地址这四个数据。我们可以发现在每条新闻的[div class="list-hd"][/div]这个标签下,存在新闻的链接地址与新闻的标题这两个数据。而我们所要做的便是利用Jsoup将这两个数据解析出来:
首先用Jsoup.connect(“所要抓取数据的网址”).get()获取到一个Document对象
Document doc = Jsoup.connect("https://voice.hupu.com/nba/").get();
用doc.select("div.list-hd")这个方法,返回一个Elements对象,封装了每条新闻[div class="list-hd"][/div]标签中的内容,数据格式为:[{新闻1},{新闻2},{新闻3},{新闻4}......]
用for循环遍历titleLinks,对于每个Element对象:
用e.select("a").text()便获取到[a][/a]间的内容,即新闻标题;
用e.select("a").attr("href")便获取到每个标签中的href的值,即新闻的链接地址Elements titleLinks = doc.select("div.list-hd");for(Element e:titleLinks){ String title = e.select("a").text(); String uri = e.select("a").attr("href");}
- 同理对于另外两个数据:新闻简介和新闻时间及来源,我们分析源代码并进行解析
- 新闻简介源代码
用如下代码获得新闻简介
Elements descLinks = doc.select("div.list-content"); for(Element e:titleLinks){ String desc = e.select("span").text(); }
- 新闻时间及来源源代码
用如下代码获得新闻时间与来源
Elements timeLinks = doc.select("div.otherInfo"); for(Element e:timeLinks){ String time = e.select("span.other-left").select("a").text(); }
- 新闻时间及来源源代码
综上,我们就获取到了我们所需要的数据了,为此我们在MainActivity中声明一个getNews()方法,在方法中,我们开启一个线程来进行数据的获取。完整代码如下:
private void getNews(){new Thread(new Runnable() {@Overridepublic void run() {try{//获取虎扑新闻20页的数据,网址格式为:https://voice.hupu.com/nba/第几页 for(int i = 1;i<=20;i++) {Document doc = Jsoup.connect("https://voice.hupu.com/nba/" + Integer.toString(i)).get();Elements titleLinks = doc.select("div.list-hd"); //解析来获取每条新闻的标题与链接地址Elements descLinks = doc.select("div.list-content");//解析来获取每条新闻的简介Elements timeLinks = doc.select("div.otherInfo"); //解析来获取每条新闻的时间与来源//for循环遍历获取到每条新闻的四个数据并封装到News实体类中for(int j = 0;j < titleLinks.size();j++){String title = titleLinks.get(j).select("a").text();String uri = titleLinks.get(j).select("a").attr("href");String desc = descLinks.get(j).select("span").text();String time = timeLinks.get(j).select("span.other-left").select("a").text();News news = new News(title,uri,desc,time);newsList.add(news);}}Message msg = new Message();msg.what = 1;handler.sendMessage(msg);}catch (Exception e){e.printStackTrace();}}}).start(); }
上一段代码相信通过备注就可以理解了,通过解析虎扑NBA新闻20页的每一页的网址,获取到每条新闻所需的数据,封装到实体类News中,再加入到MainActivity中声明的泛型为News的List即newsList中。等全部20页数据都获取到之后,用Message.what=1来作为数据加载完成的标志,并用Handler.sendMessage()将子线程的消息发送到主线程,通知主线程数据已加载完成,可以将数据加载到ListView上显示出来。
5.剩下的就简单了 ,为ListView做相关的配置
- news_item.xml:为ListView的item指定布局。放置三个TextView用来显示新闻标题,新闻概要,新闻时间及来源;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="vertical"android:layout_height="match_parent"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:layout_marginRight="5dp"android:layout_marginBottom="5dp"android:id="@+id/news_title"android:gravity="center_horizontal"android:textColor="#000"android:textSize="18sp"/><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="12sp"android:id="@+id/news_desc"android:layout_marginBottom="6dp"android:layout_marginLeft="10dp"android:gravity="center_horizontal" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/news_time"android:layout_marginBottom="6dp"android:textSize="10sp"android:textColor="#708090"android:gravity="center_horizontal"android:layout_marginRight="30dp" /></LinearLayout>
- NewsAdapter.java:为ListView加载数据
public class NewsAdapter extends BaseAdapter {private List<News> newsList;private View view;private Context mContext;private ViewHolder viewHolder;public NewsAdapter(Context mContext, List<News> newsList) {this.newsList = newsList;this.mContext= mContext;}@Overridepublic int getCount() {return newsList.size();}@Overridepublic Object getItem(int position) {return newsList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {view = LayoutInflater.from(mContext).inflate(R.layout.news_item,null);viewHolder = new ViewHolder();viewHolder.newsTitle = (TextView) view.findViewById(R.id.news_title);viewHolder.newsDesc = (TextView)view.findViewById(R.id.news_desc);viewHolder.newsTime = (TextView)view.findViewById(R.id.news_time);view.setTag(viewHolder);} else {view = convertView;viewHolder = (ViewHolder) view.getTag();}viewHolder.newsTitle.setText(newsList.get(position).getNewsTitle());viewHolder.newsDesc.setText(newsList.get(position).getDesc());viewHolder.newsTime.setText("来自 : "+newsList.get(position).getNewsTime());return view;}class ViewHolder{TextView newsTitle;TextView newsDesc;TextView newsTime;}}
6.建立NewsDisplayActivity用于显示新闻的具体内容。
布局activity_display_news.xml:简单放入一个WebView,用于显示新闻
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><WebViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/web_view"></WebView></LinearLayout>
NewsDisplayActivity.java
public class NewsDisplayActvivity extends AppCompatActivity {private String newsUrl;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_news_display);newsUrl = getIntent().getStringExtra("news_url");WebView webView = (WebView) findViewById(R.id.web_view);webView.getSettings().setJavaScriptEnabled(true);webView.setWebViewClient(new WebViewClient());webView.loadUrl(newsUrl);}
}
7.MainActivity用getNews()获取到数据后,在handlerMessage()方法里接受到子线程获取完数据的消息后,开始为ListView加载数据。并为ListView的item设置点击事件,当点击item时,将该item所对应的新闻的网址传递给NewsDisplayActivity,NewsDisplayActivity得到网址后用WebView加载该网址,便可看到新闻
public class MainActivity extends AppCompatActivity {private List<News> newsList;private NewsAdapter adapter;private Handler handler;private ListView lv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);newsList = new ArrayList<>();lv = (ListView) findViewById(R.id.news_lv);getNews();handler = new Handler(){@Overridepublic void handleMessage(Message msg) {if(msg.what == 1){adapter = new NewsAdapter(MainActivity.this,newsList);lv.setAdapter(adapter);lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {News news = newsList.get(position);Intent intent = new Intent(MainActivity.this,NewsDisplayActvivity.class);intent.putExtra("news_url",news.getNewsUrl());startActivity(intent);}});}}};}private void getNews(){new Thread(new Runnable() {@Overridepublic void run() {try{//获取虎扑新闻20页的数据,网址格式为:https://voice.hupu.com/nba/第几页for(int i = 1;i<=20;i++) {Document doc = Jsoup.connect("https://voice.hupu.com/nba/" + Integer.toString(i)).get();Elements titleLinks = doc.select("div.list-hd"); //解析来获取每条新闻的标题与链接地址Elements descLinks = doc.select("div.list-content");//解析来获取每条新闻的简介Elements timeLinks = doc.select("div.otherInfo"); //解析来获取每条新闻的时间与来源for(int j = 0;j < titleLinks.size();j++){String title = titleLinks.get(j).select("a").text();String uri = titleLinks.get(j).select("a").attr("href");String desc = descLinks.get(j).select("span").text();String time = timeLinks.get(j).select("span.other-left").select("a").text();News news = new News(title,uri,desc,time);newsList.add(news);}}Message msg = new Message();msg.what = 1;handler.sendMessage(msg);}catch (Exception e){e.printStackTrace();}}}).start();}}
最后记得在AndroidManifest中添加网络请求的权限
2017.05.19更新(Github同步更新)
由于虎扑新闻网页做了调整,去除了新闻简介,所以这部分内容就获取不到了,所以相应的要修改代码,只需要getNews()方法中做三个修改
如下图,获取新闻简介的两句代码注释掉,News构造对象时,新闻简介参数传入null。这样改动较小,界面会丑点,自行调整便可。
源码下载地址:请戳这里
总结:虽然只是一个简单的应用,但还是有所收获。有什么错误的地方,欢迎指出。菜鸟的点滴积累,希望能早日有所成长
转自:http://www.cnblogs.com/AaronPasi/p/6344123.html
Jsoup抓取网页数据完成一个简易的Android新闻APP相关推荐
- 抓取网页数据并解析Android
抓取网页数据并解析 标签: 网页抓取jsoupAndroid 2016-03-02 13:54 1262人阅读 评论(1) 收藏 举报 分类: Android开发(原创)(7) 版权声明:本文为博 ...
- python爬网页数据用什么_初学者如何用“python爬虫”技术抓取网页数据?
原标题:初学者如何用"python爬虫"技术抓取网页数据? 在当今社会,互联网上充斥着许多有用的数据.我们只需要耐心观察并添加一些技术手段即可获得大量有价值的数据.而这里的&quo ...
- web scraper 抓取网页数据的几个常见问题
如果你想抓取数据,又懒得写代码了,可以试试 web scraper 抓取数据. 相关文章: 最简单的数据抓取教程,人人都用得上 web scraper 进阶教程,人人都用得上 如果你在使用 web s ...
- php如何抓取网页内容,php如何抓取网页数据?
php抓取网页数据header("Content-type: text/html; charset=utf-8"); //$url = "https://www.cnbl ...
- 【.NET】使用HtmlAgilityPack抓取网页数据
原文:[.NET]使用HtmlAgilityPack抓取网页数据 刚刚学习了XPath路径表达式,主要是对XML文档中的节点进行搜索,通过XPath表达式可以对XML文档中的节点位置进行快速定位和访问 ...
- python 抓取网页数据
python 抓取网页数据 此文解决如何从不同网页爬取数据的问题及注意事项,重点说明requests库的应用. 在开始之前,要郑重说明一下,不是每一个网页都可以爬取数据哦.有的网页涉及个人隐私或其他敏 ...
- excel数据自动录入网页_Excel自动抓取网页数据,数据抓取一键搞定
网站上的数据源是我们进行统计分析的重要信息源.我们在生活中常常听到一个词叫"爬虫",能够快速抓取网页上的数据,这对于数据分析相关工作来说极其重要,也是必备的技能之一.但是爬虫大多需 ...
- Python 爬虫篇#笔记02# | 网页请求原理 和 抓取网页数据
目录 一. 网页请求原理 1.1 浏览网页的过程 1.2 统一资源定位符URL 1.3 计算机域名系统DNS 1.4 分析浏览器显示完整网页的过程 1.5 客户端THHP请求格式 1.6 服务端HTT ...
- python 实时抓取网页数据并进行 筛查
python 实时抓取网页数据并进行 筛查 爬取数据的两种方法 : 方法 1 : 使用 requests.get() 方法,然后再解码,接着 调用 BeautifulSoup API 首先看 head ...
最新文章
- 2018未来科学大奖揭晓:袁隆平、马大为、林本坚等7位科学家获奖
- HTTP请求过程详解
- LINUX系统管理员技术(Admin)-------第三天
- Cocos2d-x 3.2 EventDispatcher事件分发机制
- 将字符串添加负数_Go语言实现LeetCode算法:8 字符串转整数
- 无法安装软件之解决其一 (windows installer服务篇)
- nn.Dataparallel pytorch 平行计算的两种方法
- 百胜软件牵手晨光文具打造电商信息化平台
- jQuery 的CSS选择器 中 使用变量的方法
- sourceTree 的使用
- html 文本框 p,Javascript实现HTML表单form多个HttpPost请求
- python中RGB缓冲区红蓝颠倒的解决办法
- Python之爬取安居客网二手房小区详情页数据
- vs2010 sp1 安装错误,重新安装错误
- 如何加声调口诀_拼音标声调的规则口诀
- 巧用Excel函数进行数据转置
- 多路耦合器(有源分离器)在无线通讯中的应用
- 机器人焊钳选型_焊接机器人选型资料
- ETC是什么,ETC系统主要有哪几部分构成?
- 提高百度SEM竞价托管效果常见的4大问题