今天来说说怎么使用Jsoup来爬取网上的数据在自己的APP里面显示,一般都会配合ListView或者Recyclerview 这两个控件。我们这次使用ListView来尝试一下,顺便也讲一下ListView的基本用法。
从最基本使用ListView开始,首先在activity_main.xml中添加一个ListView控件,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.a28062.listviewts.MainActivity">
<ListView
android:id="@+id/lv_mytest"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
然后在去MainActivity主类中添加如下代码:
public class MainActivity extends AppCompatActivity {
private String[] mData = {"aa","bb","cc","dd","ee","ff","gg","hh","jj","kk","ll","rr","xx","tt"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.lv_mytest);
ArrayAdapter adapter = new ArrayAdapter(MainActivity.this,android.R.layout.simple_list_item_1,mData);
listView.setAdapter(adapter);
}
}
这就是ListView的最基本的用法,从中我们知道了要用好ListView我们要有一个适配器(adapter),要自定义Item.XML,甚至还需要一个Bean类。Bean类不懂的话可以上网搜搜,简单来说就是一个处理数据的类。
下面开始我们的主题,Jsou爬去网页信息并在ListView中显示,Jsoup的用法你们可以参考官方文档:
Jsoup中文文档:https://www.ibm.com/developerworks/cn/java/j-lo-jsouphtml/
Jsoup下载链接:https://jsoup.org/download
首先我们先确认我们要爬取的目标网站,这里我选择了http://www.qkankan.com/asia/korea/medium/。
打开网站后找到我们想要爬取的内容记下来(这个网站的内容会变化,之后如果有人发现没法正常显示自己调整就好),我选择了这一段:
注意我画红框的地方是要让大家清楚看到我接下来要爬取的内容对应的是什么。我要爬取一个标题,链接,内容,图片这四个内容,所以我们现在可以创建一个Bean类来处理了,上代码:
public class MyBean {
private String detailUrl;//链接
private String imageUrl;//图片
private String title;//标题
private String detail;//内容
public MyBean(String detailUrl, String imageUrl, String title, String detail){
this.detail = detail;
this.detailUrl = detailUrl;
this.imageUrl = imageUrl;
this.title = title;
}
public String getDetailUrl() {
return detailUrl;
}
public void setDetailUrl(String detailUrl) {
this.detailUrl = detailUrl;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
}
然后创建一个适配器(adapter),考虑到优化问题我直接用了 ViewHolder,不知道这个东西的可以去参考郭神的第一行代码。上图:
public class NewAdapter extends BaseAdapter {
private List<MyBean> newsList;
private View view;
private Context mContext;
private ViewHolder viewHolder;
public NewAdapter(Context mContext,List<MyBean> obj){
this.mContext = mContext;
this.newsList = obj;
}
@Override
public int getCount() {
return newsList.size();
}
@Override
public Object getItem(int position) {return newsList.get(position);}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.news_item, null);
viewHolder = new ViewHolder();
viewHolder.newsTitle = (TextView) view.findViewById(R.id.item_1);
viewHolder.newsDesc = (TextView)view.findViewById(R.id.item_2);
viewHolder.newsTime = (TextView)view.findViewById(R.id.item_3);
viewHolder.newsImage = (TextView) view.findViewById(R.id.item_4);
view.setTag(viewHolder);
} else {
view = convertView;
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.newsTitle.setText(newsList.get(position).getTitle());
viewHolder.newsDesc.setText(newsList.get(position).getDetail());
viewHolder.newsTime.setText(newsList.get(position).getDetailUrl());
viewHolder.newsImage.setText(newsList.get(position).getImageUrl());
return view;
}
class ViewHolder{
TextView newsImage;
TextView newsTitle;
TextView newsDesc;
TextView newsTime;
}
}
好了现在就差获取网页信息以及适配到ListView中显示了,我们回到主类中。
首先Jsoup是不能在主线程执行,所以我们要创建一个子线程去发送网络请求,请求到数据后我们还要通过handler来返回主线程更新UI。思路理清了我们上代码具体看看:
public class MainActivity extends AppCompatActivity {
private ListView listView;
private Handler handler;
private List<MyBean> mdata ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mdata = new ArrayList<>();
listView = (ListView) findViewById(R.id.lv_mynews);
myThread();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what == 1){
NewAdapter newAdapter = new NewAdapter(MainActivity.this,mdata);
listView.setAdapter(newAdapter);
}
}
};
}
public void myThread(){
new Thread(){
@Override
public void run() {
try{
//创建一个Document对象去链接目标网站获取
Document doc = Jsoup.connect("http://www.qkankan.com/asia/korea/medium/").get();
//创建一个Elements对象获取div.slist的所以内容
Elements els = doc.select("div.slist");
Log.d("TAG", els.toString());
//遍历Elements对象的内容
for (int j = 0 ;j<els.size();j++) {
String title = els.select("img").attr("alt");//获取标题内容
String detail = els.select("p").text();//获取新闻内容
String detailUrl = els.select("a").attr("href");//获取下个页面链接
String imageUrl = els.select("img").attr("src");//获取图片链接
Log.e("TAG", "详情链接:" + els.get(j).select("a").attr("href"));
Log.e("TAG", "标题:" + els.get(j).select("img").attr("alt"));
Log.e("TAG", "图片地址:" + els.get(j).select("img").attr("src"));
Log.e("TAG", "内容:" + els.get(j).select("p").text());
MyBean news = new MyBean(detailUrl, imageUrl, title, detail);//把每次获取的内容放进MyBean对象里
mdata.add(news);
}
Message msg = new Message();//创建一个Message对象
msg.what = 1;
handler.sendMessage(msg);//通过Handler切换主线程
}catch (Exception e){
Log.d("TAG",e.toString());
}
}
}.start();
}
}
这样就完成了用Jsoup的数据适配到ListView中显示的功能了,如果大家发现有什么可以修改的更好的话请指出,谢谢大家。
原创链接:https://blog.csdn.net/weixin_40600325/article/details/79962855