jsoup的简单实用兼谈一个简单的汇率查询(原创)

简介: jsoup的简单实用兼谈一个简单的汇率查询(原创)

通过网上公开的数据进行汇率查询,这里用到了jsoup的包,详细可以参考另外一篇我的文章《jSoup Cookbook-提取数据 7 使用选择器语法查找元素》

下面附上代码rate.java 这个是数据结构类,无需更多的解释

package com.nbcio.baishicha.rate;
import java.io.Serializable;
public class Rate implements Serializable {
/**
* 
*/
private static final long serialVersionUID = 1L;
private String title;
private String name;
private String english;
private String xhbuy;//现汇买入价
private String xcbuy;//现钞买入价
private String sell;//卖出价
private String picurl;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setEnglish(String english) {
this.english = english;
}
public String getEnglish() {
return english;
}
public void setSell(String sell) {
this.sell = sell;
}
public String getSell() {
return sell;
}
public void setXcbuy(String xcbuy) {
this.xcbuy = xcbuy;
}
public String getXcbuy() {
return xcbuy;
}
public void setXhbuy(String xhbuy) {
this.xhbuy = xhbuy;
}
public String getXhbuy() {
return xhbuy;
}
public void setPicurl(String picurl) {
this.picurl = picurl;
}
public String getPicurl() {
return picurl;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
} 
}

界面是个简单的listview,这里用到了异步调用与一个ArrayAdapter的适配器

package com.nbcio.baishicha.rate;
import java.util.ArrayList;
import com.nbcio.baishicha.R;
import android.app.ListActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class RateList extends ListActivity {
protected final static int MENU_DELETE = Menu.FIRST;
protected final static int MENU_DEMO = Menu.FIRST + 1;
public  final static String SER_KEY = "com.nbcio.baishicha.rate";
ArrayList<Rate> alrate = new ArrayList<Rate>();
private RateAdapter listAdapter;
View viewProgressBar;
RateData api = new RateData();
TextView title;
Button btreturn,btrefresh;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ratelist);
viewProgressBar = findViewById(R.id.rateProgress);
//Bundle extras=getIntent().getExtras(); //getIntent()返回启动这个activity的intent
        this.setTitle(getResources().getText(R.string.app_name) + "-" + "中国银行外汇牌价");
        title = (TextView) findViewById(R.id.tvtitle);
        btreturn = (Button)findViewById(R.id.btreturn);
btreturn.setSelected(true);
btreturn.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
            RateList.this.finish();
            }
        });
update();
}
void update() {
// 刷新msg的内容
try {
GetFundData uptask = new GetFundData();
         uptask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class GetFundData extends AsyncTask<String, Integer, String> {
// 后面尖括号内分别是参数,进度(publishProgress用到),返回值 类型
protected String doInBackground(String... code) {
// TODO Auto-generated method stub
try {
String str = api.getAllRate();
alrate = (ArrayList<Rate>) api.ReadRateHtml(str);
} catch (Exception e) {
e.printStackTrace();
return "error";
}
return "ok";//返回大写的OK好像有问题,不知道为什么?
}
protected void onProgressUpdate(Integer... progress) {
// tv.setText(String.valueOf(progress[0]));
// 这个函数在doInBackground调用publishProgress时触发,虽然调用时只有一个参数
// 但是这里取到的是一个数组,所以要用progesss[0]来取值
// 第n个参数就用progress[n]来取值
}
protected void onPostExecute(String result) {
// 生成动态数组,加入数据
String temp = "ok";
if ((alrate == null) (alrate.size() == 0)) {
Toast.makeText(RateList.this, "读取信息出错!",
Toast.LENGTH_LONG).show();
viewProgressBar.setVisibility(View.GONE);
return;
}
if (result.compareTo(temp) == 0) {
title.setText(alrate.get(0).getTitle());
viewProgressBar.setVisibility(View.GONE);
// 添加点击
RateList.this.setListAdapter(getAdapter());
RateList.this.getListView().setOnItemClickListener(
new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0,
View v, int position, long id) {
RateList.this.getAdapter().setSelectItem(position);
RateList.this.getAdapter().notifyDataSetInvalidated();
Intent intent = new Intent(RateList.this,
RateDetail.class);
Bundle mBundle = new Bundle();
mBundle.putSerializable(SER_KEY, alrate
.get(position));
intent.putExtras(mBundle);
startActivity(intent);
}
});
}
// doInBackground返回时触发,换句话说,就是doInBackground执行完后触发
// 这里的result就是上面doInBackground执行后的返回值,所以这里是"执行完毕"
}
}
private RateAdapter getAdapter(){
if(this.listAdapter==null){
listAdapter=new RateAdapter(this, alrate);
}
return listAdapter;
}
}

RateAdapter 从ArrayAdapter继承过来,这里因为数据也不大,所以就简单用了这个,但对数据大的时候这个效率比较低

package com.nbcio.baishicha.rate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.nbcio.baishicha.R;
import android.app.Activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class RateAdapter extends ArrayAdapter<Rate> {
int selectItem=-1;
public RateAdapter(Activity activity,
List<Rate> rateList) {
super(activity, 0, rateList);
}
private Map<Integer, View> viewMap = new HashMap<Integer, View>();
public  void setSelectItem(int selectItem) {   
        this.selectItem = selectItem;   
   }    
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = this.viewMap.get(position);
if (rowView == null) {
LayoutInflater inflater = ((Activity) this.getContext())
.getLayoutInflater();
rowView = inflater.inflate(R.layout.raterow, null);
Rate rateBean = this.getItem(position);
if (rateBean != null) {
TextView tvName = (TextView) rowView.findViewById(R.id.tvratename);
tvName.setTextColor(Color.BLACK);
tvName.setText(rateBean.getName());
TextView tvXhbuy = (TextView) rowView.findViewById(R.id.tvxhbuy);
tvXhbuy.setTextColor(Color.BLACK);
tvXhbuy.setText(rateBean.getXhbuy());
TextView tvXcbuy = (TextView) rowView.findViewById(R.id.tvxcbuy);
tvXcbuy.setTextColor(Color.BLACK);
tvXcbuy.setText(rateBean.getXcbuy());
TextView tvSell = (TextView) rowView.findViewById(R.id.tvsell);
tvSell.setTextColor(Color.BLACK);
tvSell.setText(rateBean.getSell());
}
viewMap.put(position, rowView);
}
if (position == selectItem) {   
rowView.setBackgroundColor(Color.WHITE);   
        }    
        else {   
        rowView.setBackgroundColor(Color.TRANSPARENT);   
        }      
return rowView;
}
}

下面就是重点介绍的RateData数据解析类

根据返回的HTML页面通过jsoup进行解析过滤

package com.nbcio.baishicha.rate;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import com.nbcio.baishicha.common.SysUtil;
/**
 * 汇率查询类
 * 主要从相应汇率网站获得数据
 * 
 * @author lvqiyong
 */
public class RateData {
private static final String WAIHUI = "https://www.usd-cny.com/";
private static final String CHARTURL = "https://qq.ip138.com/hl.asp?from=";
/**
* 获取所有实时汇率列表内容的HTML数据
* 
* @return String
* @throws Exception
* @author lvqiyong
*/
public String getAllRate()
throws Exception {
return new String(SysUtil.getRequest(WAIHUI, "gb2312"));
}
/**
* 获取查询的汇率趋势图的html数据
* 
* @return String
* @throws Exception
* @author lvqiyong
*/
public String getRateChart(String key)
throws Exception {
return new String(SysUtil.getRequest(CHARTURL + key + "&to=CNY&q=100", "utf-8"));
}
/**
* 通过读取onlinecha的html数据,根据信息写到ArrayList<Rate>中
* @param String
* @return ArrayList<Rate>
* @throws Exception
* @author lvqiyong
*/
ArrayList<Rate> ReadRateHtml(String html) {
ArrayList<Rate> alrate = new ArrayList<Rate>();
try {
Document dom = Jsoup.parse(html);
Elements titleNode = dom.select("h1.top");
String title = titleNode.text();
title = title + dom.select("span.STYLE1").text();
title = title.replace("中国银行外汇牌价", "");
title = title.replace("工商银行汇率", "");
title = title.replace("实时汇率表", "");
Elements root = dom.select("TABLE[BORDERCOLOR]").select("tr");
int j = 0;
for (Element element : root) {
               if (j==0) {
j++;
continue;
}
Elements rateNode = element.select("td");
int i = 0;
Rate rate = new Rate();
for (Element items : rateNode) {
switch (i) {
case 0:
Elements numNode = items.select("a");
String name = numNode.text();
int start = name.indexOf(" ") + 1;
rate.setName(name);
rate.setEnglish(name.substring(start).trim());
break;
case 1:
String tmp = "";
tmp = items.text();
tmp = tmp.replace(" ", "");
rate.setXhbuy(tmp);
break;
case 2:
String xctmp = "";
xctmp = items.text();
xctmp = xctmp.replace(" ", "");
rate.setXcbuy(xctmp);
break;
case 3:
String selltmp = "";
selltmp = items.text();
selltmp = selltmp.replace(" ", "");
rate.setSell(selltmp);
break;
default:
break;
}
i++;
}
rate.setTitle(title);
alrate.add(rate);
j++;
}
} catch (Exception e) {
e.printStackTrace();
}
return alrate;
}
/**
* 通过读取趋势图数据,根据js信息写到String中
* @param String
* @return String
* @throws Exception
* @author lvqiyong
*/
String ReadRateChart(String html) {
String scharturl = "";
try {
Document dom = Jsoup.parse(html);
Elements root = dom.select("img");
scharturl = root.attr("src");
} catch (Exception e) {
e.printStackTrace();
}
return scharturl;
}
}
相关文章
|
7月前
|
消息中间件 缓存 数据库
GitHub置顶半个月!78w字百亿级并发设计(全彩PDF),竟出自京东
想要设计一个高并发的系统,就要从根源出发。为什么会有高并发?高并发又有哪些厉害之处呢?其实很简单,刚开始系统都是连接数据库的,但是数据库在支撑到每秒并发两三千上万的时候,很多系统是支撑不住的。因此很多公司刚开始做的时候,技术如果不是很好,业务又发展太快,就有可能导致系统无法承受压力,发生宕机的情况,因此需要设计一个高并发的系统。
|
5天前
|
存储 前端开发 数据可视化
网上图书销售网站的设计与实现(论文+源码)_kaic
网上图书销售网站的设计与实现(论文+源码)_kaic
|
5月前
|
Dubbo NoSQL Java
炸裂!阿里内部10W字面试手册,竟在GitHub访问量破百万
所谓 “金三银四”,是找工作的最佳季节。跳槽,你动心了吗? 年后返工往往伴随着离职大潮,相信有不少程序员朋友都想在金三银四这个招聘黄金期里找到一份更加心仪的工作。优秀的面试技巧往往能让大家事半功倍,了解面试题、良好的简历和提问套路,也是面试者突围而出的关键。还有时间,建议耐心读完全文,充分准备去拿到你的Dream Offer。
|
6月前
|
算法 Java 程序员
这份Java面试指南在GitHub上超百万下载量!现惨遭大厂集体封杀
作为程序员,你反感面试的时候做题吗?有很多公司在面试中都会有让求职者现场做题的环节,尤其是与开发相关的岗位,比较常见。
|
8月前
|
Java 程序员 应用服务中间件
膜拜!首次公布Java10W字面经,Github访问量破百万
Java面试 “金九银十”这个字眼对于程序员应该是再熟悉不过的了,每年的金九银十都会有很多程序员找工作、跳槽等一系列的安排。说实话,面试中7分靠能力,3分靠技能;在刚开始的时候介绍项目都是技能中的重中之重,它也是可以决定一次面试的成败的,那么在面试的时候你会如何介绍自己、熟练回答面试官的问题以及有条理的介绍项目呢?
|
Java
排名前16的Java工具类
排名前16的Java工具类
155 0
|
编解码 数据可视化 BI
CSDN:借助工具对【本博客访问来源】进行数据图表可视化(网友主要来自美国、新加坡、日本、英德加澳等)——记录数据来源截止日期20200718晚上22点
CSDN:借助工具对【本博客访问来源】进行数据图表可视化(网友主要来自美国、新加坡、日本、英德加澳等)——记录数据来源截止日期20200718晚上22点
CSDN:借助工具对【本博客访问来源】进行数据图表可视化(网友主要来自美国、新加坡、日本、英德加澳等)——记录数据来源截止日期20200718晚上22点
|
存储 Python
用 Python 帮财务小妹解决 PDF 拆分,小妹说太棒了。。。
用 Python 帮财务小妹解决 PDF 拆分,小妹说太棒了。。。
用 Python 帮财务小妹解决 PDF 拆分,小妹说太棒了。。。
|
Web App开发 SQL 搜索推荐
知网“哭穷”:赔不起 1200 亿;微信公众号文章留言显示 IP 属地;程序员延寿指南霸榜 GitHub;联想高层大降薪|架构周报
本周架构视点:知网“哭穷”:赔不起 1200 亿;微信公众号文章留言显示 IP 属地;程序员延寿指南霸榜 GitHub;联想高层大规模降薪;网易云音乐起诉腾讯音乐;GitHub 弃用 io;ARM 安谋中国 430 多名员工联名签署公开信,反对软银夺权;Firefox:我们不会卖给亿万富翁
139 0
知网“哭穷”:赔不起 1200 亿;微信公众号文章留言显示 IP 属地;程序员延寿指南霸榜 GitHub;联想高层大降薪|架构周报
|
编译器
昨日万圣节ABAP怪兽级代码谜团,公布答案啦
昨日万圣节ABAP怪兽级代码谜团,公布答案啦
115 0
昨日万圣节ABAP怪兽级代码谜团,公布答案啦