作业内容是 截取学校教学平台网站的新闻列表,然后在Android界面中用ListView显示出来,点击ListView中的Button可以弹出详细内容的新Activity。
本次学习重点如下:
1.截取HTML代码
2.用Jsoup解析HTML代码
详细要求:
1.BNUZH网络教学综合平台 打开之后可以看到通知公告。
2.查看源代码,我们可以发现是这段的内容
本次实验目的就是要抓取这里的代码
每一条<li>的内容都要转化并且在Android中显示出来
3.效果图1
为了方便显示 上面是一个TextView用来测试 截取的代码
下面的ListView是用于显示后来的经过转化的元素
这样看来,很快就能做到片总NGA客户端那种论坛抓取的形式啦。
实现过程以及重点:
1.用Android获取HTML源代码(UTF-8 不然默认是GB2312中文会乱码)
这部分网络连接需要用到异步线程 更新UI记得在onPostExecuted中完成
/* 连接EOL的方法 返回整个网页经过截取之后的的源代码 */
public String ConnectEOL() {
String result = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL_EOL);
HttpResponse response = httpclient.execute(httppost);
String Res = EntityUtils.toString(response.getEntity(), "UTF-8");
int st = Res.indexOf("<div class=\"notifywrap\">");
int ed = Res.indexOf("<div class=\"notify-more\">");
String content = Res.substring(st, ed);
st = content.indexOf("<ul>") + 4;
ed = content.indexOf("</ul>");
content = content.substring(st, ed);
result = content;
} catch (Exception e) {
Log.d(TAG, e.toString());
}
return result;
}
这里先获得整个HTML页面的代码 用String保存
然后对这个字符串进行一步步的截取 使得只剩下ul标签里面的多个li标签。
2.用Jsoup解析HTML代码获取了
这串代码之后,如何获取li标签里面的span标签里面的通知时间呢?
如何获取li里面的a标签的href值 和title值呢?~请用Jsoup解析HTML 转化成的String字符串。
Jsoup需要下载 百度Jsoup 下载1.7.3jar包导入。
地址 Jsoup 下载地址
导入Jsoup.jar包请注意,你以为在BuildPath中Add ExJar就行了?Android4.0之后更新了导入额外包的方式 需要你手动将jar包复制到工程目录下的libs文件夹。然后再从BuildPath中选择倒入,才不会报错。
下面是Jsoup解析上面这段代码
/* 对源代码进行解析截取的方法 返回一个News数组 */
public List<News> getNews(String HTMLCode) {
List<News> newsList = new ArrayList<News>();
Document doc = Jsoup.parse(HTMLCode);
Log.d(TAG, "解析html中");
Elements lis = doc.getElementsByTag("li");
Log.d(TAG, "lis的size " + lis.size());
for (Element li : lis) {
String newstime = li.getElementsByTag("span").text();
String newstitle = li.getElementsByTag("a").text();
String newsurl = li.getElementsByTag("a").attr("href");
newsurl=newsurl.replace("../../", "http://eol.bnuz.edu.cn/eol/");
Log.d(TAG, newstime);
Log.d(TAG, newstitle);
Log.d(TAG, newsurl);
News newst=new News();
newst.setNewsTime(newstime);
newst.setNewsTitle(newstitle);
newst.setNewsUrl(newsurl);
newsList.add(newst);
}
return newsList;
}
先用一个Elements 元素组来储存所有的<li></li>标签中间的内容。
然后遍历这个Elements组 我们把<li></li>里面诸如<span></span> <a></a>中的span 和a 叫做Tag ,也就是标签。 用getElementsByTag(标签名)来取值 返回一个Elements类型。如果需要得到的是<span>Aquariuslt</span> 中Aquariuslt的值,则需要用这个Elements.text()方法取值。
如果要获取<a href="www.baidu.com"></a> 则需要用Elements.attr("href")方法来获得这个www.baidu.com 字符串。
在这里,我发现a标签里面的href值都是相对路径,所以我机智的用replace更改了URL使得是绝对路径。
下面是源代码:
Activity_news_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".NewsList" >
<TextView
android:id="@+id/TV_HTMLCode"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_above="@+id/LV_Result"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:scrollbars="vertical" />
<ListView
android:id="@+id/LV_Result"
android:layout_width="match_parent"
android:layout_height="230dp"
android:layout_alignLeft="@+id/TV_HTMLCode"
android:layout_alignParentBottom="true" >
</ListView>
</RelativeLayout>
NewsList.java
package bnuz.alt.eol_newscatcher;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import bnuz.alt.news.News;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
@SuppressWarnings("unused")
public class NewsList extends Activity {
private TextView TV_HTMLCode;
private String URL_EOL = "http://eol.bnuz.edu.cn/eol/homepage/common/",
TAG = "ATAG";
private List<News> NewsList;
private ListView LV_Result;
private ArrayAdapter<String> LV_Adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_list);
LV_Result = (ListView) findViewById(R.id.LV_Result);
TV_HTMLCode = (TextView) findViewById(R.id.TV_HTMLCode);
TV_HTMLCode.setMovementMethod(ScrollingMovementMethod.getInstance());
ConnectTask C1 = new ConnectTask();
C1.execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.news_list, menu);
return true;
}
public class ConnectTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
String result = ConnectEOL();
return result;
}
@Override
protected void onPostExecute(String result) {
// TV_HTMLCode.setText(result);
NewsList = getNews(result);
List<String> NewsTitles = new ArrayList<String>();
for (News news : NewsList) {
TV_HTMLCode.append(news.getNewsTitle() + "\n");
TV_HTMLCode.append(news.getNewsTime() + "\n");
TV_HTMLCode.append(news.getNewsUrl() + "\n");
NewsTitles.add(news.getNewsTitle());
}
/* 为ListView添加适配器 */
LV_Adapter = new ArrayAdapter<String>(NewsList.this,
android.R.layout.simple_list_item_1, NewsTitles);
LV_Result.setAdapter(LV_Adapter);
/* 为ListView添加点击打开对应网页功能 */
LV_Result.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
final Uri uri = Uri.parse(NewsList.get(arg2).getNewsUrl());
final Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
}
});
super.onPostExecute(result);
}
}
/* 连接EOL的方法 返回整个网页经过截取之后的的源代码 */
public String ConnectEOL() {
String result = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL_EOL);
HttpResponse response = httpclient.execute(httppost);
String Res = EntityUtils.toString(response.getEntity(), "UTF-8");
int st = Res.indexOf("<div class=\"notifywrap\">");
int ed = Res.indexOf("<div class=\"notify-more\">");
String content = Res.substring(st, ed);
st = content.indexOf("<ul>") + 4;
ed = content.indexOf("</ul>");
content = content.substring(st, ed);
result = content;
} catch (Exception e) {
Log.d(TAG, e.toString());
}
return result;
}
/* 对源代码进行解析截取的方法 返回一个News数组 */
public List<News> getNews(String HTMLCode) {
List<News> newsList = new ArrayList<News>();
Document doc = Jsoup.parse(HTMLCode);
Log.d(TAG, "解析html中");
Elements lis = doc.getElementsByTag("li");
Log.d(TAG, "lis的size " + lis.size());
for (Element li : lis) {
String newstime = li.getElementsByTag("span").text();
String newstitle = li.getElementsByTag("a").text();
String newsurl = li.getElementsByTag("a").attr("href");
newsurl = newsurl.replace("../../", "http://eol.bnuz.edu.cn/eol/");
Log.d(TAG, newstime);
Log.d(TAG, newstitle);
Log.d(TAG, newsurl);
News newst = new News();
newst.setNewsTime(newstime);
newst.setNewsTitle(newstitle);
newst.setNewsUrl(newsurl);
newsList.add(newst);
}
return newsList;
}
}
News类
package bnuz.alt.news;
public class News {
private String newsTime;
private String newsUrl;
private String newsTitle;
public News() {
}
public News(String newsTitle, String newsTime, String newsUrl) {
this.newsTime = newsTime;
this.newsUrl = newsUrl;
this.newsTitle = newsTitle;
}
public String getNewsTime() {
return newsTime;
}
public void setNewsTime(String newsTime) {
this.newsTime = newsTime;
}
public String getNewsUrl() {
return newsUrl;
}
public void setNewsUrl(String newsUrl) {
this.newsUrl = newsUrl;
}
public String getNewsTitle() {
return newsTitle;
}
public void setNewsTitle(String newsTitle) {
this.newsTitle = newsTitle;
}
}