这几天做一个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的坑太大了,跳进去一定要多百度,多阅读代码,把代码都消化才有进步。
总结
以上是内存溢出为你收集整理的Android爬取网页JSON数据详细教程【新手向】全部内容,希望文章能够帮你解决Android爬取网页JSON数据详细教程【新手向】所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)