这几天做一个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厘米、棕色就是篮球对应的属性值
那么实体类又是什么,返回来看我们上面的例子,篮球就是实体,篮球类就是篮球这个种类,
拥有篮球类的三个属性不一定属于篮球,因为他有可能是足球。
但是篮球一定属于篮球类。有趣的哲学概念。
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的坑太大了,跳进去一定要多百度,多阅读代码,把代码都消化才有进步。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。