当前位置: 首页 > news >正文

安卓应用开发学习:聚合数据API获取天气预报

一、引言

上个月我通过腾讯位置服务,实现了手机定位应用的开发学习。最近在看软件书籍时,又看到了聚合数据API方面的内容。 书上介绍了聚合数据天气预报API的应用,不过书上的代码看得有些难受,我到聚合数据官网,对天气预报API的接口文档进行了研究,感觉比书上的要简单。于是,我参照官网的接口文档设计查询部分的代码,UI等设计则借鉴了书上的内容,完成了这个应用的开发。实现的效果如下图:

二、聚合数据平台选择API

聚合数据平台提供了很多的API,其中免费的API也不少。要使用该平台的API自然需要先注册用户了。

注册号用户,登录后,先完成实名认证,否则无法使用API。我是后知后觉,申请API的时候出现了要求实名认证的提示。

大体的流程在网站上有说明。

完成注册和认证后,进入API页面,选择免费接口 (免费API接口工具大全 - 聚合数据)。我们要用到的天气预报接口就在第一行。

点击天气预报,进入天气预报接口页面。点击“立即申请”。这个页面里还可以获得接口的相关介绍和示例代码,方便我们进行应用开发。

完成申请后就可以在“个人中心 - 数据中心 - 我的API”中看到申请到的API了。聚合数据对免费接口有限制,普通会员只能申请3个。大多数免费接口每天的请求次数为50次,进行开发学习还是够用了。调用API需要的Key也在这个页面里。

完成了API的申请,就可以着手进行软件的设计开发了。

三、软件设计

我的天气预报应用的界面设计参考了书上的样式,但书上的代码将城市名写死了,我希望支持输入城市名进行查询。因此设计UI时,在页面顶部添加了SearchView组件,用于输入城市名称,输入后按下软键盘中的搜索按钮,执行获取天气预报操作。界面的中间部分放置了几个TextView组件用于显示实时天气信息,界面下部使用纵向的LinearLayout布局设置,该布局做了圆角处理,其下放置了多个TextView组件用于显示未来5天的预报信息。有参照做起来就很快了。

逻辑代码的设计则花了一些时间,主要是书上的代码看着不够简洁,比官网提供的示例要复杂不少。我就没有照搬书上的内容做,而是综合了书上的代码与官网示例进行的设计。其中GET请求部分的代码基本照搬了“接口文档”中提供的Java示例。有所区别的是,需要添加try语句,否则会报错。

官网提供了接口测试功能,可以先在接口测试页面查看获取天气预报的请求详情和返回结果。方便后续的代码设计。

这个API的调用接口URI格式如下:

http://apis.juhe.cn/simpleWeather/query?key=key&city=%E8%8B%8F%E5%B7%9E

其中key在“个人中心 - 数据中心 - 我的API”中获取。city则是从SearchView组件中获取。我将GET请求放在了SearchView组件的监听器中执行。监听器响应搜索按钮触发,获取组件中的文本内容,并将其传递给获取天气预报的方法。

获取天气预报的方法,我是参考了官网的java示例代码(如下):

package cn.juhe.test;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;public class JavaGet {public static void main(String[] args) throws Exception {String apiKey = "你申请的key";String apiUrl = "http://apis.juhe.cn/simpleWeather/query";HashMap<String, String> map = new HashMap<>();map.put("key", apiKey);map.put("city", "苏州");URL url = new URL(String.format(apiUrl + "?" + params(map)));BufferedReader in = new BufferedReader(new InputStreamReader((url.openConnection()).getInputStream()));String inputLine;StringBuffer response = new StringBuffer();while ((inputLine = in.readLine()) != null) {response.append(inputLine);}in.close();System.out.println(response);}public static String params(Map<String, String> map) {return map.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&"));}
}

上述代码也是将城市名写死的,且获取到的结果直接打印输出,不符合我们的实际应用需求,得修改,但关键的代码基本是可以照搬的。

在做逻辑代码设计时,我遇到了两个问题:

1.一开始,我的GET请求代码是放在主线程中执行的,结果测试时出现了报错。网上搜索后,才了解到从Android 4.0 之后不能在主线程中请求HTTP,需要将GET请求放在分线程中执行。

2.在分线程中执行GET请求获取到天气预报的信息后,我在分线程里更新UI的代码,结果测试时又报错了。一搜,Android不允许在分线程中直接修改UI界面,可以使用runOnUiThread方法更新UI界面。

解决了这两个问题,其它方面就很顺利了,完成后测试了几次,还可以。

请求次数可以在“个人中心-数据中心-我的API”找到天气预报,点击“统计”按钮,可以查看调用情况。

四、代码展示

最终的代码如下:

1. 界面设计文件  activity_weather.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".WeatherActivity"><TextViewandroid:id="@+id/tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="天气预报"android:textSize="24sp"android:textStyle="bold"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><LinearLayoutandroid:id="@+id/linearLayout"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:orientation="horizontal"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/tv_title"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginEnd="10dp"android:text="城市"android:textSize="17sp" /><android.widget.SearchViewandroid:id="@+id/sv_cityName"android:layout_width="match_parent"android:layout_height="40dp"android:background="@drawable/shape_round_bg_gray"android:iconifiedByDefault="true"android:imeOptions="actionSearch"android:queryHint="请输入关键字"android:textColor="@color/gray_78"android:textSize="15sp" /></LinearLayout><ScrollViewandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_marginTop="10dp"android:background="@color/blue_415"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/linearLayout"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:orientation="vertical" ><TextViewandroid:id="@+id/tv_result"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/tv_cityName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="城市名"android:textColor="@color/white"android:textSize="24sp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_realTime_temp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="~℃"android:textColor="@color/white"android:textSize="32sp"android:textStyle="bold" /><TextViewandroid:id="@+id/tv_realTime_weather"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="天气"android:textColor="@color/white"android:textSize="32sp"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_realTime_dir"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="风向"android:textColor="@color/white"android:textSize="22sp"android:textStyle="bold" /><TextViewandroid:id="@+id/tv_realTime_pow"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="风级"android:textColor="@color/white"android:textSize="22sp"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_realTime_hum"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="湿度~"android:textColor="@color/white"android:textSize="22sp"android:textStyle="bold" /><TextViewandroid:id="@+id/tv_realTime_aqi"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="空气质量指数~"android:textColor="@color/white"android:textSize="22sp"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:background="@drawable/radius_border_15"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:text="5天预报"android:textSize="20sp" /><TextViewandroid:id="@+id/tv_date1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:text="日期1" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_temp1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="~℃" /><TextViewandroid:id="@+id/tv_weather1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="天气" /><TextViewandroid:id="@+id/tv_dir1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="风向" /></LinearLayout><TextViewandroid:id="@+id/tv_date2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:text="日期2" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_temp2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="~℃" /><TextViewandroid:id="@+id/tv_weather2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="天气" /><TextViewandroid:id="@+id/tv_dir2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="风向" /></LinearLayout><TextViewandroid:id="@+id/tv_date3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:text="日期3" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_temp3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="~℃" /><TextViewandroid:id="@+id/tv_weather3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="天气" /><TextViewandroid:id="@+id/tv_dir3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="风向" /></LinearLayout><TextViewandroid:id="@+id/tv_date4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:text="日期4" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_temp4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="~℃" /><TextViewandroid:id="@+id/tv_weather4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="天气" /><TextViewandroid:id="@+id/tv_dir4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="风向" /></LinearLayout><TextViewandroid:id="@+id/tv_date5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="10dp"android:text="日期5" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="10dp"android:orientation="horizontal"><TextViewandroid:id="@+id/tv_temp5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="~℃" /><TextViewandroid:id="@+id/tv_weather5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="天气" /><TextViewandroid:id="@+id/tv_dir5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="风向" /></LinearLayout></LinearLayout></LinearLayout></ScrollView></androidx.constraintlayout.widget.ConstraintLayout>

2. 逻辑代码 WeatherActivity.java

import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;
import android.widget.SearchView;
import android.widget.TextView;import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;  // 与官网示例不同,官网是net.sf.json.JSONObjectimport java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;public class WeatherActivity extends AppCompatActivity {private final static String TAG = "WeatherActivity";private SearchView sv_cityName;  // 搜索框private TextView tv_cityName;  // 显示城市名private TextView tv_realTime_temp;  // 显示实时温度private TextView tv_realTime_weather;  // 显示实时天气private TextView tv_realTime_dir;  // 显示实时风向private TextView tv_realTime_pow;  // 显示实时风级private TextView tv_realTime_hum;  // 显示实时湿度private TextView tv_realTime_aqi;  // 显示空气质量指数private TextView tv_date1, tv_date2, tv_date3, tv_date4, tv_date5;  // 日期private TextView tv_temp1, tv_temp2, tv_temp3, tv_temp4, tv_temp5;  // 温度private TextView tv_weather1, tv_weather2, tv_weather3, tv_weather4, tv_weather5;  // 天气private TextView tv_dir1, tv_dir2, tv_dir3, tv_dir4, tv_dir5;  // 风向private String mCityName;  // 保存用户在搜索框中输入的城市名// 天气情况查询接口地址private static final String API_URL = "http://apis.juhe.cn/simpleWeather/query";// 接口请求Key(在聚合数据网站申请天气预报API后生成的AppKey)private static final String API_KEY = "***********************";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_weather);sv_cityName = findViewById(R.id.sv_cityName);  // 城市名搜索框// 实时天气tv_cityName = findViewById(R.id.tv_cityName);tv_realTime_temp = findViewById(R.id.tv_realTime_temp);tv_realTime_weather = findViewById(R.id.tv_realTime_weather);tv_realTime_dir = findViewById(R.id.tv_realTime_dir);tv_realTime_pow = findViewById(R.id.tv_realTime_pow);tv_realTime_hum = findViewById(R.id.tv_realTime_hum);tv_realTime_aqi = findViewById(R.id.tv_realTime_aqi);// 未来5天预报天气tv_date1 = findViewById(R.id.tv_date1);tv_date2 = findViewById(R.id.tv_date2);tv_date3 = findViewById(R.id.tv_date3);tv_date4 = findViewById(R.id.tv_date4);tv_date5 = findViewById(R.id.tv_date5);tv_temp1 = findViewById(R.id.tv_temp1);tv_temp2 = findViewById(R.id.tv_temp2);tv_temp3 = findViewById(R.id.tv_temp3);tv_temp4 = findViewById(R.id.tv_temp4);tv_temp5 = findViewById(R.id.tv_temp5);tv_weather1 = findViewById(R.id.tv_weather1);tv_weather2 = findViewById(R.id.tv_weather2);tv_weather3 = findViewById(R.id.tv_weather3);tv_weather4 = findViewById(R.id.tv_weather4);tv_weather5 = findViewById(R.id.tv_weather5);tv_dir1 = findViewById(R.id.tv_dir1);tv_dir2 = findViewById(R.id.tv_dir2);tv_dir3 = findViewById(R.id.tv_dir3);tv_dir4 = findViewById(R.id.tv_dir4);tv_dir5 = findViewById(R.id.tv_dir5);// 设置搜索框监听器sv_cityName.setOnQueryTextListener(new SearchView.OnQueryTextListener() {// 当点击搜索按钮时触发该方法@Overridepublic boolean onQueryTextSubmit(String s) {sv_cityName.clearFocus();  // 移除焦点mCityName = s;// Android 4.0 之后不能在主线程中请求HTTPnew Thread(() -> queryWeather (mCityName)).start();  // 分线程中获取天气信息return false;}// 当搜索内容改变时触发该方法@Overridepublic boolean onQueryTextChange(String s) {return false;}});}/*** 根据城市名查询天气情况** @param cityName  城市名称*/private void queryWeather(String cityName) {HashMap<String, String> map = new HashMap<>();  //组合参数map.put("city", cityName);map.put("key", API_KEY);String queryParams = params(map);try {URL url = new URL(API_URL + "?" + queryParams);Log.d(TAG, "URL=" + url);BufferedReader in = new BufferedReader(new InputStreamReader((url.openConnection()).getInputStream()));String inputLine;StringBuffer response = new StringBuffer();  // StringBuffer是线程安全的,StringBuilder效率更高,但不是线程安全的while ((inputLine = in.readLine()) != null) {response.append(inputLine);}in.close();// Log.d(TAG, "查询天气返回的结果:");// Log.d(TAG, response.toString());// 将获取到的结果转换为JSONObject,从中获取天气信息try {JSONObject jsonObject = new JSONObject(response.toString());int error_code = jsonObject.getInt("error_code");if (error_code == 0) {JSONObject result = jsonObject.getJSONObject("result");String city = result.getString("city");// 获取实时天气数据JSONObject realtime = result.getJSONObject("realtime");String temp = realtime.getString("temperature");  // 温度String hum = realtime.getString("humidity");  // 湿度String info = realtime.getString("info");  // 天气String dir = realtime.getString("direct");  // 风向String pow = realtime.getString("power");  // 风级String aqi = realtime.getString("power");  // 空气质量指数// 获取未来5天的天气数据JSONArray futureArray = result.getJSONArray("future");JSONObject f1 = futureArray.getJSONObject(0);String date1 = f1.getString("date");String temp1 = f1.getString("temperature");String weather1 = f1.getString("weather");String dir1 = f1.getString("direct");JSONObject f2 = futureArray.getJSONObject(1);String date2 = f2.getString("date");String temp2 = f2.getString("temperature");String weather2 = f2.getString("weather");String dir2 = f2.getString("direct");JSONObject f3 = futureArray.getJSONObject(2);String date3 = f3.getString("date");String temp3 = f3.getString("temperature");String weather3 = f3.getString("weather");String dir3 = f3.getString("direct");JSONObject f4 = futureArray.getJSONObject(3);String date4 = f4.getString("date");String temp4 = f4.getString("temperature");String weather4 = f4.getString("weather");String dir4 = f4.getString("direct");JSONObject f5 = futureArray.getJSONObject(4);String date5 = f5.getString("date");String temp5 = f5.getString("temperature");String weather5 = f5.getString("weather");String dir5 = f5.getString("direct");// 分线程不能直接修改UI界面,可以使用runOnUiThread方法更新UI界面runOnUiThread(() -> {tv_cityName.setText(city);// 更新实时天气tv_realTime_temp.setText(String.format(Locale.CHINESE, "%s%s", temp, "℃"));tv_realTime_weather.setText(info);tv_realTime_dir.setText(dir);tv_realTime_pow.setText(pow);tv_realTime_hum.setText(String.format(Locale.CHINESE, "%s%s", "湿度:", hum));tv_realTime_aqi.setText(String.format(Locale.CHINESE, "%s%s", "空气质量指数:", aqi));// 更新未来5天预报天气tv_date1.setText(date1);tv_temp1.setText(temp1);tv_weather1.setText(weather1);tv_dir1.setText(dir1);tv_date2.setText(date2);tv_temp2.setText(temp2);tv_weather2.setText(weather2);tv_dir2.setText(dir2);tv_date3.setText(date3);tv_temp3.setText(temp3);tv_weather3.setText(weather3);tv_dir3.setText(dir3);tv_date4.setText(date4);tv_temp4.setText(temp4);tv_weather4.setText(weather4);tv_dir4.setText(dir4);tv_date5.setText(date5);tv_temp5.setText(temp5);tv_weather5.setText(weather5);tv_dir5.setText(dir5);});  // 使用runOnUiThread更新界面} else {Log.d(TAG, "调用接口失败:" + jsonObject.getString("reason"));}} catch (JSONException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}/*** 将map型转为请求参数型** @param map  map型保存的参数*/private static String params(Map<String, String> map) {return map.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining("&"));}
}

相关文章:

安卓应用开发学习:聚合数据API获取天气预报

一、引言 上个月我通过腾讯位置服务&#xff0c;实现了手机定位应用的开发学习。最近在看软件书籍时&#xff0c;又看到了聚合数据API方面的内容。 书上介绍了聚合数据天气预报API的应用&#xff0c;不过书上的代码看得有些难受&#xff0c;我到聚合数据官网&#xff0c;对天气…...

设计模式 - 抽象工厂模式

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、抽象工…...

塔子哥选数字-阿里淘天2024笔试(codefun2000)

题目链接 塔子哥选数字-阿里淘天2024笔试(codefun2000) 题目内容 塔子哥有一个长为n的数组a。他定义一个数组的权值为&#xff1a;数组中不同的数字个数。 塔子哥希望从数组a中选出在个数子&#xff0c;使得这k个数字组成的数组权值最大&#xff0c;请你帮帮塔子哥。 输入描述…...

【leetcode】杨辉三角(Java语言描述)

杨辉三角 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]] …...

Vue - 关于vue-kinesis 移动动画组件

Vue - 关于vue-kinesis 移动动画组件 vue-kinesis可以根据鼠标移动或滚动条来控制元素动画的动画效果&#xff1b;除此之外&#xff0c;vue-kinesis 还可以设置音频文件&#xff0c;根据音频频率来控制动画的跳动效果。 一、安装vue-kinesis Vue2版本&#xff1a; 1.安装 …...

leetCode- - - 链表

目录 1.反转链表&#xff08;leetcode206&#xff09; 2. 链表内指定区间反转&#xff08;leetcode92&#xff09; 3.链表中的节点每k个一组翻转&#xff08;leetcode25&#xff09; 4.合并两个排序的链表&#xff08;leetcode21&#xff09; 5.链表的中间节点&#xff08…...

Ashok:一款多功能开源网络侦查OSINT工具

关于Ashok Ashok是一款多功能开源网络侦查公开资源情报OSINT工具&#xff0c;该工具可谓是OSINT领域中的瑞士军刀&#xff0c;广大研究人员可以使用该工具轻松完成网络侦查任务。 侦察是渗透测试的第一阶段&#xff0c;这意味着在计划任何实际攻击之前收集信息。因此&#xff…...

没有获取淘宝API的资质怎么获取淘宝数据

淘宝是头部电商平台之一&#xff0c;每个自研商家或电商软件服务商想要开发电商管理功能模板就少不了要对接淘宝API。淘宝API是在淘宝开放平台提供的&#xff0c;自研商家和软件服务商接入淘宝开放平台需要经过一系列审核和申请流程&#xff0c;要求资质和相关资料符合对应的要…...

SQL手工注入

目录 1.判断是否存在sql注入点 1.1我们在地址栏中输入?id1 1.2我们在地址栏中输入?id-- 2.联合查询 2.1首先知道表格有几列&#xff0c;如果报错就是超过列数&#xff0c;如果显示正常就是没有超出列数。 2.2爆出显示位&#xff0c;就是看看表格里面哪一列是在页面显示…...

【SQL】大的国家

目录 题目 分析 代码 题目 World表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | name | varchar | | continent | varchar | | area | int | | population | int | | gdp | bigint | ----…...

8月5日学习笔记 glibc安装与安全用户角色权限

一&#xff0c;glibc安装 https://www.mysql.com/ 官⽹ https://downloads.mysql.com/archives/community/ https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-li nux-glibc2.12-x86_64.tar 安装步骤 1.安装依赖库 [rootlocalhost ~]# yum list installed |g…...

DrissionPage 一个替代selenium的pip --- 一个可以接管正在运行的chrome包

DrissionPage 一个替代selenium的pip包&#xff0c;持续更新 1、加载内容&#xff0c;并接管chrome浏览器 from DrissionPage import ChromiumPage, ChromiumOptions page ChromiumPage(addr_or_opts127.0.0.1:9222) print(page.title)ul page.eles(idform-submit) for i i…...

爬虫入门--了解相关工具

目录 1.爬虫与python 2.第一个爬虫 3.web请求的全过程 3.1服务器渲染 3.2前端JS渲染 4.浏览器工具 4.1Elements 4.2Console 4.3Source 4.4network&#xff08;重点&#xff09; 5.小结 1.爬虫与python 首先我们要知道&#xff0c;爬虫一定要用Python么? 非也~…...

django项目中通用的分页组件

文章目录 分页组件pager组件代码 分页组件 应用分页组件&#xff0c;需要以下两个步骤&#xff1a; 视图函数中&#xff1a;&#xff08;先获取queryset&#xff0c;将request和queryset传入分页组件对象中&#xff0c;得到生成的html标签&#xff09; def customer_list(requ…...

想实现ubuntu搭建sqli-labs靶场

目录 首先前期的nginx和php部署完成​编辑​编辑 Xftp导入sqli-labs 遇到了的问题 它提示我们请检查db-creds.inc 去尝试解决这个问题 尝试修改MySQL root密码 修改db-creds.inc配置 再次尝试依旧失败 思考&#xff1a;会不会是MySQL版本过高的原因 重新下载MySQL5.7.…...

tp8 按日期分组查出数据

1.如果数据库里时间字段都是时间戳,使用mysql中的from_unixtime()函数 field("from_unixtime(create_time,%Y-%m-%d) as time,group_concat(id)")->group(time)->select()2. 如果数据库是普通的日期格式&#xff08;如2024-01-02 01:23:50&#xff09;&#x…...

单例模式(懒汉模式,饿汉模式)

单例的饿汉模式&#xff1a;在主函数未调用之前该单例就已经存在了&#xff0c;所以不存在线程安全的问题。 class Singleton { private: Singleton(){} public:static Singleton s1;static Singleton* GetInstance(){return &s1;}Singleton(const Singleton&) delet…...

【Qt】Item Widgets 多元素控件

Qt中提供的多元素控件有&#xff1a; QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView 上述控件分为Widget和View&#xff0c;其区别如下&#xff1a; 以QTableWidget和QTableView为例 QTableView是基于MVC(Model-View-Controller)设计的控件。QTableView自身…...

sharded_inference_engine:MLXDynamicShardInferenceEngine;step

目录 sharded_inference_engine:MLXDynamicShardInferenceEngine 类属性 方法 __init__(self) async def infer_prompt(self, shard: Shard, prompt: str, inference_state: Optional[str] = None) -> (np.ndarray, str, bool) async def infer_tensor(self, shard: …...

JAVA开发学习-day21

JAVA开发学习-day21 1. 删除表单数据 根据ElementUI的官方组件指南&#xff0c;为表单每列的数据添加删除按钮 <el-table :data"tableData" style"width: 100%"><el-table-column prop"id" label"ID" width"180"…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...