使用jsoup加载网页数据(一)

真的好久没更新博客了,最近做一个csdn的客户端用到了jsoup技术用于获取网页的数据和图片,很好用。只需要下载一个jsoup.jar的包然后布置到自己的项目的环境就可以用了。废话不多说,直接上图片

使用jsoup加载网页数据(一)_第1张图片使用jsoup加载网页数据(一)_第2张图片

这是通过jsoup直接获取到的数据然后展示出来。简述一下用到的技术主要有Jsoup解析html,异步加载任务,ImageLoader加载图片。

我们在浏览网页的时候都可以按F12查看网页代码,然后可以查看里面的各种元素。

使用jsoup加载网页数据(一)_第3张图片

可以看到每个新闻都是一个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




    

    

        

        

            

                
            

            

                
            
        
    


activity_main.xml



    

    


了解ImageLoader就知道它是单一实例的,所以必须要在application里面实例。

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);
	}
}


注意,必须要到AndroidManifest.xml里面注册这个application,          android:name="com.sdf.android_jsoup.MyApplication".../>

最后就是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);
		}
	}

}

这里因为是涉及到网络加载数据,所以必须要异步加载,我是用了AsyncTask这个类来加载的,你也可以选择使用thread来加载。

以上就是这次的内容了,需要源码的可以留言。

别忘了在AndroidManifext.xml里添加网络权限和读写权限。








你可能感兴趣的:(Android开发日记,Android,异步)