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;
}
}
相关文章
|
8月前
|
关系型数据库 MySQL
Mysql基础第九天,过滤数据
Mysql基础第九天,过滤数据
54 0
Mysql基础第九天,过滤数据
|
7月前
|
Java
排名前16的Java工具类
排名前16的Java工具类
45 0
|
8月前
|
SQL 大数据 HIVE
每天一道大厂SQL题【Day28】腾讯数据提取(一)搞笑类型视频的曝光点赞数据
每天一道大厂SQL题【Day28】腾讯数据提取(一)搞笑类型视频的曝光点赞数据
127 0
|
存储 C++
【PAT甲级 - C++题解】1076 Forwards on Weibo
【PAT甲级 - C++题解】1076 Forwards on Weibo
63 0
|
自然语言处理 分布式计算 Scala
使用Spark实现微博内容解析-每月前十最热词汇
简单spark+scala的demo,具体为map,flatmap,reducebykey等算子的运用
244 0
【硬着头皮】 你在筛选List里面的数据么?
【硬着头皮】 你在筛选List里面的数据么?
108 0
【硬着头皮】 你在筛选List里面的数据么?
|
存储
《C游记》 第陆章 - 数据类型悟正法 解析存储定风魔(壹)
《C游记》 第陆章 - 数据类型悟正法 解析存储定风魔(壹)
156 0
|
存储 编译器 C语言
《C游记》 第陆章 - 数据类型悟正法 解析存储定风魔(贰)
《C游记》 第陆章 - 数据类型悟正法 解析存储定风魔(贰)
136 0
CSDN博客排名记录
CSDN博客排名记录
183 0
CSDN博客排名记录
|
大数据 应用服务中间件 Linux
Python网络爬虫(正则, 内涵段子,猫眼电影, 链家爬取)
python、python爬虫、网络爬虫、爬虫框架、selenium、requests、urllib、数据分析、大数据、爬虫爬取静态网页、爬虫基础
2641 0