Android爬取网页JSON数据详细教程【新手向】

这几天做一个Android获取Json的任务,发现Jsoup只能获取静态页面,无法获取动态页面的Json数据。

有同学给我更正:Jsoup可以爬取动态页面,但必须要加请求头(data),以下为正确例子:

String url = "你的网页接口";
Map data = Maps.newHashMap();
data.put("countryCode", "+86");
data.put("mobile", mobile);
data.put("password", "f20332f07cdaab9ec0472655a83438d4");
data.put("invitionCode", "PU9HFMNMZ2FL");
data.put("validateCode", codeCallable);
data.put("geetest_challenge", challenge);
data.put("geetest_validate", validate);
data.put("geetest_seccode", validate + "|jordan");
String json = JSON.toJSONString(data);
Connection.Response response = Jsoup.connect(url).ignoreContentType(true).data(data).requestBody(json)
.header("Accept", "application/json, text/plain, */*")
.header("Content-Type", "application/json;charset=UTF-8")
.method(Connection.Method.POST).timeout(70000).execute();
System.out.println(response.body());

我换了一个思路,用是阿里巴巴alibaba:fastjson第三方包获取json数据,并可以直接转为为实体类,

几行代码就可以解决。代码编写的效率非常高,不得不称赞马爸爸牛逼。

我们先在Gradle Scripts下找到build.gradle(Modele:app)的build.gradle下加入这一行代码

    implementation 'com.alibaba:fastjson:1.2.10'

导入第三方库就完成了。

爬取的网页:https://www.6tennis.com/schedule

爬取第三方库的方法很简单,先打开你要爬取得网页,打开你的谷歌浏览器,按F12进入开发者调试模式

然后刷新一下网页页面,就会显示这个网页嗅探到的一些文件,只需要单击小放大镜,然后输入你需要搜索的数据(可以是JSON里面的数据或者文件名)

单击上图第三步骤,就会发现右手方框框里出现一系列的JSON数据。

{"code":"200","message":"\u8bf7\u6c42\u6210\u529f","data":{"total":69,"list":[{"id":8,"game_name":"ATP Cup","is_grandslm":0,"game_level":"750","ground_name":"\u786c

\u5730","match_time":"01.03-01.12"},{"id":13,"game_name":"\u5361\u5854\u5c14\u516c\u5f00\u8d5b","is_grandslm":0,"game_level":"250","ground_name":"\u786c

\u5730","match_time":"01.06-01.11"},{"id":9,"game_name":"\u963f\u5fb7\u83b1\u5fb7\u56fd\u9645\u8d5b","is_grandslm":0,"game_level":"250","ground_name":"\u786c

\u5730","match_time":"01.12-01.18"},{"id":15,"game_name":"\u5965\u514b\u5170\u559c\u529b\u516c\u5f00\u8d5b","is_grandslm":0,"game_level":"250","ground_name":"\u786c

\u5730","match_time":"01.13-01.18"},{"id":16,"game_name":"\u6fb3\u5927\u5229\u4e9a\u7f51\u7403\u516c

\u5f00\u8d5b","is_grandslm":1,"game_level":"2000","ground_name":"\u786c\u5730","match_time":"01.20-02.03"}]}}

 现在我们理清一下思路,

一、首先我们要通过代码从android端通过get或者post方式访问网页,并获取网页的内容

二、获取到网页的内容以后要对Json数据进行分析,并把格式转换为我们相应的JSON格式

三、获取到JSON后转换我们对应的实体类,并存在Arraylist实体表里。

四、我们再把Arraylist实体表里的Json数据循环输入到前台的不同的TextView里,然后把TextView添加前台UI

以上思路基本都在后面的代码MainActivity.class的doInBackground和getView方法里实现

三步骤为什么要用实体类?

新手应该很觉得懵逼,相信学java的朋友都应该清楚,实体类是一个抽象的概念。

举个栗子:我们假设篮球   形状:圆的  长:30厘米  颜色:棕色,

那么这里的篮球就是实体,形状、长度、颜色就是属性,圆、30厘米、棕色就是篮球对应的属性值

那么实体类又是什么,返回来看我们上面的例子,篮球就是实体,篮球类就是篮球这个种类,

拥有篮球类的三个属性不一定属于篮球,因为他有可能是足球。

但是篮球一定属于篮球类。有趣的哲学概念。

我们再来看看JSON数据的实体类代码:

News.class

public class News {
    private int id;//编号
    private String game_name;//赛事名称
    private int is_grandslm;
    private String game_level;//赛事级别
    private String ground_name;//场地名
    private String match_time;
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getGame_name() {
        return game_name;
    }

    public void setGame_name(String game_name) {
        this.game_name = game_name;
    }

    public int getIs_grandslm() {
        return is_grandslm;
    }

    public void setIs_grandslm(int is_grandslm) {
        this.is_grandslm = is_grandslm;
    }

    public String getGame_level() {
        return game_level;
    }

    public void setGame_level(String game_level) {
        this.game_level = game_level;
    }

    public String getGround_name() {
        return ground_name;
    }

    public void setGround_name(String ground_name) {
        this.ground_name = ground_name;
    }

    public String getMatch_time() {
        return match_time;
    }

    public void setMatch_time(String match_time) {
        this.match_time = match_time;
    }
}

细心观察,我们取出一条JSON数据的内容和实体类的属性是一一对应的。

{"id":8,"game_name":"ATP Cup","is_grandslm":0,"game_level":"750","ground_name":"\u786c

\u5730","match_time":"01.03-01.12"}

另外实体类一般都需要有get、set方法,方便获取或传递实体类的属性值。

代码都有注释,直接上代码,

MainActivity.java实现代码:

package com.example.tennisdatas;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView Lv_main_list;
    private List<News> NewsList = new ArrayList<News>();
    private ProgressDialog progressDialog;
    private MyAdapter myAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Lv_main_list =(ListView) findViewById(R.id.Lv_main_list);
        //实例化进度条对话框
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("亲,正在玩命加载中哦!");
        ////实例化适配器
        myAdapter = new MyAdapter();
        Lv_main_list.setAdapter(myAdapter);
    }



    //适配器
    class MyAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return NewsList.size();
        }

        @Override
        public Object getItem(int i) {
            return NewsList.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        //添加JSON数据对应出来的TextView,显示到主界面,非主要代码
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            LinearLayout layout = new LinearLayout(MainActivity.this);
            layout.setOrientation(LinearLayout.VERTICAL);
            TextView textViewID = new TextView(MainActivity.this);
            textViewID.setText(NewsList.get(i).getId()+"\t"+" ");
            TextView textViewGameName = new TextView(MainActivity.this);
            textViewGameName.setText(NewsList.get(i).getGame_name()+"\t");
            TextView textViewIs_grandslm= new TextView(MainActivity.this);
            textViewIs_grandslm.setText(NewsList.get(i).getIs_grandslm()+"\t");
            TextView textViewGame_level = new TextView(MainActivity.this);
            textViewGame_level.setText(NewsList.get(i).getGame_level()+"\t");
            TextView textViewGround_name = new TextView(MainActivity.this);
            textViewGround_name.setText(NewsList.get(i).getGround_name()+"\t");
            TextView textViewMatch_time= new TextView(MainActivity.this);
            textViewMatch_time.setText(NewsList.get(i).getMatch_time()+"\t");
            layout.addView(textViewID);
            layout.addView(textViewGameName);
            layout.addView(textViewIs_grandslm);
            layout.addView(textViewGame_level);
            layout.addView(textViewGround_name);
            layout.addView(textViewMatch_time);

            return layout;
        }
    }


    //获取xml数据
    public void getJson(View view){
        new MyTask().execute();
    }
    //通过异步任务类获取数据
    class MyTask extends AsyncTask {
        private  News jsonTeacherEntity;
        //准备执行
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog.show();
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            //首先我们要通过代码从android端通过get或者post方式访问网页,并获取网页的内容
            //path为获取JSON数据的接口
            String path="https://www.6tennis.com/api/getScheduleList";
            try {
                URL url = new URL(path);
                //获取连接对象
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                //设置请求方式
                httpURLConnection.setRequestMethod("POST");
                //设置连接超时
                httpURLConnection.setConnectTimeout(5000);
                //获取响应码
                int code = httpURLConnection.getResponseCode();

                if (code==200)
                {
                    //响应成功,获取服务器返回过来的数据
                    final InputStream is = httpURLConnection.getInputStream();
                    //测试数据
                    StringBuffer stringBuffer = new StringBuffer();
                    String str=null;
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    while ((str=br.readLine())!=null){
                        stringBuffer.append(str);

                    }

                    //使用fastJson解析Json
                    Log.e("Json数据", "Json数据: "+stringBuffer.toString() );
                    /* 
                        因为JSON数据里有一些我们不需要的属性,我们需要把
                       需要的Json数据提取出来,这里我写得比较复杂,方便学习
                                */
                    String NewsData = stringBuffer.toString();
                    JSONObject jb = JSON.parseObject(NewsData);
                    String Newsdata2 = jb.getString("data");
                    JSONObject jb1 = JSON.parseObject(Newsdata2);
                    String Newsdata3 = jb1.getString("list");
                    Log.e("Newsdata3", "Newsdata3"+Newsdata3);
                    List<News> DNews = JSON.parseArray(Newsdata3, News.class);

                    for (News TT:DNews)
                    {
                        jsonTeacherEntity = new News();
                        int id = TT.getId();
                        String game_name = TT.getGame_name();
                        int is_grandslm = TT.getIs_grandslm();
                        String game_level = TT.getGame_level();
                        String ground_name = TT.getGround_name();
                        String match_time = TT.getMatch_time();
                        jsonTeacherEntity.setId(id);
                        jsonTeacherEntity.setGame_name(game_name);
                        jsonTeacherEntity.setGame_level(game_level);
                        jsonTeacherEntity.setIs_grandslm(is_grandslm);
                        jsonTeacherEntity.setGround_name(ground_name);
                        jsonTeacherEntity.setMatch_time(match_time);
                        NewsList.add(jsonTeacherEntity);
                    }
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            //通知适配器发生改变
            myAdapter.notifyDataSetChanged();
            //取消进度条对话框
            progressDialog.cancel();
        }

    }

}

主界面UI代码:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="刷新"
        android:gravity="center"
        android:layout_gravity="center"
        android:onClick="getJson"
        />
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="vertical"
        android:id="@+id/Lv_main_list"
        >
    </ListView>
</LinearLayout>

代码直接复制上去,调试下,直接就可以运行。

运行截图:

作者运行环境:android studio 3.5.3 

Android的坑太大了,跳进去一定要多百度,多阅读代码,把代码都消化才有进步。 

发布了4 篇原创文章 · 获赞 28 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_37377691/article/details/105653454