真的好久没更新博客了,最近做一个csdn的客户端用到了jsoup技术用于获取网页的数据和图片,很好用。只需要下载一个jsoup.jar的包然后布置到自己的项目的环境就可以用了。废话不多说,直接上图片
这是通过jsoup直接获取到的数据然后展示出来。简述一下用到的技术主要有Jsoup解析html,异步加载任务,ImageLoader加载图片。
我们在浏览网页的时候都可以按F12查看网页代码,然后可以查看里面的各种元素。
可以看到每个新闻都是一个unit,每个unit里面有各种结点,我们只要去获得各种结点就能得到这里面的数据了(这里我讲一下我的技巧就是,遇到class,就是使用getElementsByClass,遇到一些标签比如这种的,就使用getElementsByTag来获得结点,然后在这些
下面的子标签的话就是使用child(i)来确定是第几个子标签),每个结点里包含了各种文字和图片链接,我们只要拿到这些再加载到我们的代码里就可以了。
先贴上最重要的jsoup解析html的代码
public class HttpUtil {
/**
* 根据传入的网址获取该网页的html
*
* @param urlStr
* @return
*/
public static String getHtml(String urlStr) {
StringBuffer sb = new StringBuffer();
URL url = null;
try {
url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setDoInput(true);
connection.setDoOutput(true);
if (connection.getResponseCode() == 200) {
// 得到输入流
InputStream input = connection.getInputStream();
byte[] b = new byte[1024];
int len;
while ((len = input.read(b)) != -1) {
sb.append(new String(b, 0, len, "UTF-8"));
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sb.toString();
}
/**
* 使用jsoup技术获取网页数据
*
* @param htmlStr
* @return
*/
public static List getNews(String htmlStr) {
List newses = new ArrayList();
News news = null;
Document doc = Jsoup.parse(htmlStr);
Elements units = doc.getElementsByClass("unit");
for (int i = 0; i < units.size(); i++) {
news = new News();
// 获得一个element
Element unit = units.get(i);
// 得到标题
Element h1_ele = unit.getElementsByTag("h1").get(0);
Element h1_a_ele = h1_ele.child(0);
String title = h1_a_ele.text();
news.setTitle(title);
// 得到时间
Element h4_ele = unit.getElementsByTag("h4").get(0);
Element ago_ele = h4_ele.getElementsByClass("ago").get(0);
String date = ago_ele.text();
news.setDate(date);
// 得到dl这个结点
Element dl_ele = unit.getElementsByTag("dl").get(0);
// 得到图片
Element dt_ele = dl_ele.child(0);
Element img_ele = dt_ele.child(0);
String imageLink = img_ele.child(0).attr("src");
news.setImageLink(imageLink);
// 得到内容
Element dd_ele = dl_ele.child(1);
String content = dd_ele.text();
news.setContent(content);
newses.add(news);
}
return newses;
}
}
先传入网页的url然后获得该网页的html源码,再开始使用jsoup解析,可以边看网页边解析对着看更好理解,大致用法我上面讲过了。
News是一个实体类
/**
* 实体类
*
* @author sdf
*
*/
public class News {
private String id;
// 标题
private String title;
// 图片链接
private String imageLink;
// 内容
private String content;
private String date;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageLink() {
return imageLink;
}
public void setImageLink(String imageLink) {
this.imageLink = imageLink;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
@Override
public String toString() {
return "News [id=" + id + ", title=" + title + ", imageLink="
+ imageLink + ", content=" + content + ", date=" + date + "]";
}
}
然后就是适配器的代码了,这个适配器的布局是各有各的想法了,你想怎么写就怎么写,当然写出好看优美的界面最好了
/**
* 适配器
*
* @author sdf
*
*/
public class NewsAdapter extends BaseAdapter {
private List mDatas = new ArrayList();
private LayoutInflater mInflater;
private DisplayImageOptions options;
public NewsAdapter(Context context, List data) {
mInflater = LayoutInflater.from(context);
this.mDatas = data;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.images)
.showImageForEmptyUri(R.drawable.images)
.showImageOnFail(R.drawable.images).cacheInMemory(true)
.cacheOnDisk(true).build();
}
public void addAll(List news) {
this.mDatas.addAll(news);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mDatas.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_news, null);
viewHolder = new ViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.content = (TextView) convertView
.findViewById(R.id.content);
viewHolder.date = (TextView) convertView.findViewById(R.id.date);
viewHolder.image = (ImageView) convertView
.findViewById(R.id.images);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
News news = mDatas.get(position);
viewHolder.title.setText(news.getTitle());
viewHolder.content.setText(news.getContent());
viewHolder.date.setText("发表于 " + news.getDate());
// 使用imagelaoder加载图片
if (news.getImageLink() != null) {
viewHolder.image.setVisibility(View.VISIBLE);
ImageLoader.getInstance().displayImage(news.getImageLink(),
viewHolder.image, options);
} else {
viewHolder.image.setVisibility(View.GONE);
}
return convertView;
}
class ViewHolder {
TextView title;
TextView content;
TextView date;
ImageView image;
}
}
这里用到了ImageLoader这个开源项目,不懂的先去自行百度,非常好用。
item_news.xml
public class MyApplication extends Application {
@Override
public void onCreate() {
// TODO Auto-generated method stub
// imageloader创建单一实例
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.diskCacheSize(50 * 1024 * 1024)
.tasksProcessingOrder(QueueProcessingType.LIFO).build();
ImageLoader.getInstance().init(config);
ImageLoader.getInstance().init(config);
}
}
最后就是MainActivity.class
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import com.sdf.android_jsoup.adapter.NewsAdapter;
import com.sdf.android_jsoup.bean.News;
import com.sdf.android_jsoup.util.HttpUtil;
public class MainActivity extends Activity {
private ListView listView;
private NewsAdapter mAdapter;
private ProgressBar progressBar;
private List mDatas;
// 网页的地址
public static final String NEWS_URL_YIDONG = "http://mobile.csdn.net/";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
mDatas = new ArrayList();
mAdapter = new NewsAdapter(getApplicationContext(), mDatas);
new getDataTask().execute();
listView.setAdapter(mAdapter);
}
/**
* 异步加载数据类
*
*/
class getDataTask extends AsyncTask> {
@Override
protected List doInBackground(Void... params) {
// TODO Auto-generated method stub
String html = HttpUtil.getHtml(NEWS_URL_YIDONG);
// 获得数据
mDatas = HttpUtil.getNews(html);
// 返回数据
return mDatas;
}
@Override
protected void onPostExecute(List result) {
// TODO Auto-generated method stub
// 增加数据到适配器里
mAdapter.addAll(result);
mAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
}
}
以上就是这次的内容了,需要源码的可以留言。
别忘了在AndroidManifext.xml里添加网络权限和读写权限。