Java中使用四叶天动态代理IP构建ip代理池,实现httpClient和Jsoup代理ip爬虫

news2024/12/26 19:54:31

在本次爬虫项目中,关于应用IP代理池方面,具体完成以下功能:

  1. 从指定API地址提取IP到ip池中(一次提取的IP数量可以自定义更改)

  2. 每次开始爬虫前(多条爬虫线程并发执行),从ip池中获取一条可用ip和端口号(并用此ip进行代理爬虫)

  3. 每条IP的有效时间为1~5分钟,如果爬虫过程中当前代理ip失效时,程序可以自动切换IP,并从当前爬到的页数开始继续爬虫。

目录

一、四叶天动态代理IP的使用步骤

二、在Java中动态IP代理的工具类

三、如何使用动态Ip进行网站访问

四、实际爬虫过程中的注意事项

五、代码中的亮点:


一、四叶天动态代理IP的使用步骤

想要使用ip代理池来进行代理IP爬虫,我们首先要购买一些可用IP,下面介绍一个好用实惠的IP代理网站:(https://www.siyetian.com)提供高质量的动态IP 服务 ,以下是购买和使用该服务的详细步骤:

(一)购买动态 IP 服务

  1. 注册并登录

  2. 实名认证:在使用服务前,需完成实名认证。登录后,前往实名认证页面(登录 - 四叶天HTTP),按照提示提交相关信息进行认证。

  3. 选择套餐:点击顶部导航栏“动态IP”,选择适合的动态 IP 套餐。这里我使用的是:按使用量购买,四块钱1000条IP

  4. 支付购买

(二)使用动态 IP 服务

点击顶部导航栏的提取API

我的配置如下:

①IP协议为Http

②提取数量为每次一条,

③数据格式设置为Json

④在白名单中添加本机IP

最后点击生成api链接,你会得到一个URL地址,每访问一次该地址,就会返回一条IP地址和一个端口号(同时你刚买的1000条IP中就少一条🐶)

注意事项(该部分AI生成用于凑字数,不想看可不看🐶):

  1. 设置白名单:在使用代理 IP 前,需将您的本机 IP地址 添加到白名单,以确保代理服务的正常使用。

    前往白名单设置页面:(登录 - 四叶天HTTP),添加您的本地 IP 地址。

  2. 配置代理IP:您可以在应用程序或浏览器中,设置使用获取的代理 IP。具体步骤如下:

    • 在浏览器设置:在浏览器的网络设置中,选择手动代理配置,输入获取的代理 IP 地址和端口号,保存设置。

    • 在程序设置:在您的爬虫、网络请求等程序中,按照编程语言的网络请求库要求,设置代理 IP 和端口。

  3. 验证代理有效性:在开始正式使用前,建议测试代理 IP 的有效性。您可以通过访问特定网站或使用相关工具,检查当前的外网 IP 是否与代理 IP 匹配,以确保代理设置成功。

注意事项(这是本人写的,大家要注意)

  • IP 时效性:每条动态 IP 的有效时长通常较短(这里是 1-5 分钟后就会失效),请根据您的业务需求,合理设置提取频率和使用策略,当一条IP到期时确保你的爬虫程序可以自动更换IP。

通过以上步骤,您即可购买并使用四叶天代理的动态 IP 服务,满足您的网络代理需求。

二、在Java中动态IP代理的工具类

当你购买完代理IP后,可以参考官方提供的SDK代码示例来构造自己的IP代理池,如下图:

 

但是官方代码的并不适合我的需求,因此本人自己找了一个Java工具类,用于IP代理池的构建和使用,非常方便。

代码如下(供大家参考):

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.qcby.byspringbootdemo.entity.AgencyIp;
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
​
public class YzxIpPoolUtil {
    //使用线程安全集合类存储代理ip
    private static CopyOnWriteArraySet<AgencyIp> ipSet = new CopyOnWriteArraySet<>();
​
    // 使用线程池执行IP验证任务
    static ExecutorService pool = Executors.newFixedThreadPool(10);
​
​
​
    //从ip集合中获取一个有效的代理IP,若集合中没有则返回null
    /*public static AgencyIp getAvailableIp() {
       if (!ipSet.isEmpty()) {
           Iterator<AgencyIp> iterator = ipSet.iterator();
           while (iterator.hasNext()) {
               AgencyIp ip = iterator.next();
               if (checkIpAddress(ip)) {
                   return ip;
               }else {
                   iterator.remove();
               }
           }
​
       }
       return null;
    }*/
​
    /**
     * 改进版getAvailableIp()  确保返回的ip一定有效
     * @return
     */
    public static AgencyIp getAvailableIp() {
        //更新ipSet集合,确保里面有ip且一定可用
        updateIpSet();
        for (AgencyIp ip : ipSet) {
            if (checkIpAddress(ip)) {
                return ip;
            }
        }
        return null;
    }
​
    /**
     * 更新ipSet集合,删除无效ip,如果为空则获取ip
     */
    public static void updateIpSet(){
        if (!ipSet.isEmpty()) {
            //删除无效ip
            ipSet.removeIf(ip -> !checkIpAddress(ip));
        }
​
        if (ipSet.isEmpty()) {
            //如果空,则获取ip
                getIpList();
        }
    }
​
    //抓取ip,放进ip代理池
    private static void getIpList() {
        System.out.println("正在抓取IP......");
        String apiUrl = "http://proxy.siyetian.com/apis_get.html?token=AesJWLNpXR51kaJdXTqFFeNRVS14EVJlXTn1STqFUeORUR41karlXTU1kePRVS10ERNhnTqFFe.wN2YTN0IDNzcTM&limit=1&type=0&time=&data_format=json";
​
        String resultJsonStr = null;
        try {
            resultJsonStr = getData(apiUrl);
        } catch (IOException e) {
            System.out.println("ip抓取失败,请检查URL是否正确");
            throw new RuntimeException("ip抓取失败");
        }
        JSONObject jsonObject = JSON.parseObject(resultJsonStr);
​
        // 从返回的数据中提取代理列表
        if (jsonObject.getIntValue("code") == 1) {
            JSONArray data = (JSONArray) jsonObject.get("data");
            for (int i = 0;i<data.size();i++){
                // 创建 AgencyIp 对象
                AgencyIp agencyIp = new AgencyIp();
                agencyIp.setAddress(data.getJSONObject(i).get("ip").toString());
                agencyIp.setPort((int)data.getJSONObject(i).get("port"));
​
                if (checkIpAddress(agencyIp)){
                    ipSet.add(agencyIp);
                    System.out.println("已经放入集合一个ip:"+agencyIp.toString());
                }
​
/*开启子线程检查该IP是否可用(选用)
    *如果不使用子线程,
    * 而是在主线程中依次检查每个 IP 的可用性,
    * 那么每次检查都需要等待上一次检查完成,这个过程是顺序执行的。
    * 当 IP 数量较多或者检查 IP 可用性的操作(比如发起网络请求去验证等)比较耗时的时候,
    * 主线程就会被长时间阻塞,导致后续其他代码无法及时执行,影响整个程序的响应速度和执行效率。
    * 而通过开启子线程,可以让多个 IP 的可用性检查操作并发进行,
    * 主线程不必等待每个检查操作结束就能继续往下执行其他任务,比如继续去抓取更多 IP
    * 提升了整体的执行效率。
*/
               
//                pool.execute(new Runnable() {
//                    @Override
//                    public void run() {
//                        if (checkIpAddress(agencyIp)){
//                            ipSet.add(agencyIp);
//                        }
//                    }
//                });
            }
        }else {
            System.out.println("抓取代理IP失败,状态码为0");
        }
    }
​
    // 检查代理IP地址是否有效
    public static boolean checkIpAddress(AgencyIp agencyIp) {
        if(agencyIp.getAddress()==null){
            return false;
        }
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(agencyIp.getAddress(), agencyIp.getPort()));
        HttpURLConnection connection = null;
        int retries = 3;  // 重试次数
        while (retries > 0) {
            try {
                connection = (HttpURLConnection) new URL("https://www.baidu.com/").openConnection(proxy);
                connection.setConnectTimeout(3000);  // 设置连接超时
                connection.setReadTimeout(3000);     // 设置读取超时
                connection.setUseCaches(false);
​
                if (connection.getResponseCode() == 200) {
                    System.out.println(agencyIp.getAddress() + " 该IP有效");
                    return true;
                }
            } catch (IOException e) {
                System.out.println(agencyIp.getAddress() + " 该IP无效,原因:" + e.getMessage());
                retries--;
                if (retries == 0) {
                    System.out.println(agencyIp.getAddress() + " 无效代理,尝试 " + (3 - retries) + " 次后失败");
                }
            }
        }
        return false;
    }
​
    // 获取指定url内容
    private static String getData(String requestUrl) throws IOException {
        URL url = new URL(requestUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.connect();//建立连接(可选)
        //InputStream是字节流,下行代码是把字节流转换为字符流,然后再转换为BufferedReader字符流,以便于按行读取数据
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
        //StringBuffer(线程安全的可变字符序列)
        StringBuffer buffer = new StringBuffer();
        String str;
        while ((str = reader.readLine()) != null) {
            buffer.append(str);
        }
        if (buffer.length() == 0) {
            buffer.append("[]");
        }
        String result = buffer.toString();
        reader.close();//关闭BufferedReader
        conn.disconnect();//关闭连接(可选)
        return result;
    }
​
    public static void main(String[] args) {
        updateIpSet();
        System.out.println(ipSet.toString());
    }
}
​

下面是对这段代码中每个方法的功能总结:


类变量

  • ipSet:使用线程安全的 CopyOnWriteArraySet 存储代理 IP 的集合。

  • pool:线程池,用于执行 IP 验证任务。


方法列表

  1. getAvailableIp

    • 功能:从 ipSet 中获取一个有效的代理 IP。

    • 实现:

      调用 updateIpSet 方法,确保集合中的 IP 是最新且有效的。

      遍历 ipSet,找到并返回第一个可用的 IP。

  2. updateIpSet

    • 功能:更新 ipSet,删除无效 IP。如果集合为空,则调用 getIpList 获取新的 IP。

    • 实现:

      遍历 ipSet,调用 checkIpAddress 方法,移除不可用的 IP。

      如果集合为空,调用 getIpList 抓取新的 IP。

  3. getIpList

    • 功能:从指定的 API 地址抓取代理 IP,并添加到 ipSet 中。

    • 实现:

      调用 getData 方法从指定 URL 获取 JSON 数据。

      解析 JSON,提取 IP 和端口,创建 AgencyIp 对象。

      检查每个 IP 的可用性(调用 checkIpAddress),将有效 IP 添加到集合中。

  4. checkIpAddress

    • 功能:检查代理 IP 地址是否有效。

    • 实现:

      使用 Proxy 类设置代理。

      尝试通过代理访问 https://www.baidu.com/

      如果响应码为 200,表示代理有效。

      支持多次重试(3 次)。

  5. getData

    • 功能:从指定的 URL 获取内容并返回为字符串。

    • 实现:

      通过 HttpURLConnection 建立连接。

      读取响应内容并返回。


主方法

  • main方法:

    功能:测试 updateIpSet 方法,并打印当前 ipSet 中的代理 IP。


总结

  • 核心流程:程序通过 API 抓取代理 IP,验证其可用性后存入集合,支持动态更新和多线程并发验证。

  • 线程安全:利用 CopyOnWriteArraySet 和线程池确保在多线程环境下数据操作的安全性。

三、如何使用动态Ip进行网站访问

项目逻辑:每次开始爬虫前,使用工具类从ip池中获取一条可用ip和端口号,并用此ip进行代理爬虫,以防止本机IP被封。

下面分别给出使用 JsoupHttpClient 结合代理 IP 访问网站的示例代码:


1. Jsoup 使用代理 IP

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
​
public class JsoupProxyExample {
    public static void main(String[] args) {
        // 获取代理 IP 和端口号(通过工具类获取)
        String proxyIp = "127.0.0.1";
        int proxyPort = 8080;
​
        // 要访问的目标 URL
        String targetUrl = "https://www.baidu.com";
​
        try {
            // 配置 Jsoup 使用代理 IP
            Document document = Jsoup.connect(targetUrl)
               .proxy(proxyIp, proxyPort) // 设置代理IP和端口号
                .timeout(5000)            // 设置超时时间
                .get();                   // 发送 GET 请求
​
            // 打印响应内容
            System.out.println(document.title());
        } catch (IOException e) {
            System.out.println("请求失败,错误信息: " + e.getMessage());
        }
    }
}

2. HttpClient 使用代理 IP

import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
​
import java.io.IOException;
​
public class HttpClientProxyExample {
    public static void main(String[] args) {
        // 获取代理 IP 和端口号(通过工具类获取)
        String proxyIp = "127.0.0.1";
        int proxyPort = 8080;
​
        // 要访问的目标 URL
        String targetUrl = "https://www.baidu.com";
​
        // 配置 HttpClient 使用代理ip和端口号
        HttpHost proxy = new HttpHost(proxyIp, proxyPort);
        CloseableHttpClient httpClient = HttpClients.custom()
                .setProxy(proxy) // 设置代理
                .build();
​
// 这里用 HTTP GET 请求作为演示,你也可以使用post请求并携带一些参数
        HttpGet httpGet = new HttpGet(targetUrl);
​
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet)
            // 打印响应状态码
            System.out.println("Response Status: " + response.getStatusLine());
​
            // 打印响应内容
            String responseBody = EntityUtils.toString(response.getEntity());
            System.out.println("Response Content: \n" + responseBody);
        } catch (IOException e) {
            System.out.println("请求失败,错误信息: " + e.getMessage());
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                System.out.println("关闭 HttpClient 时出错: " + e.getMessage());
            }
        }
    }
}

注意事项

  1. 超时处理:建议设置超时时间,避免长时间等待。

  2. 目标网站设置:确保目标网站允许被代理访问,并避免触发反爬机制。

可以根据你的业务场景,将上述代码与 IP 池工具类集成,实现高效的代理访问功能。

四、实际爬虫过程中的注意事项

每条IP的有效时间为1~5分钟,如果爬虫过程中当前代理ip失效时,程序可以自动切换IP,并从当前爬到的页数开始继续爬虫。

实现思路:

  1. 首先,封装一个爬虫方法crawler( ),接收参数是int类型的页码,返回信息是String类型字符串,该方法若成功执行完毕则返回"success";
  2. 用try-catch包裹爬虫核心代码,当捕捉到异常后,调用工具类的checkIpAddress( )方法检查当前ip是否有效,若当前ip有效,则代表异常不是因为IP失效引起的,此时应手动抛出“爬虫异常”,并自定义异常信息;若当前ip已经失效,则很有可能因为是ip失效引起的异常,此时我们返回一个Json格式的字符串,其中记录爬虫中断时的页码和关键字。
  3. 当收到爬虫方法crawler( )返回的字符串str后,检查str,若是"success"则表示本次爬虫成功;否则,则用JSON.isValid( )方法解析该字符串,若解析成功则表示当前需要更换新的代理ip:然后①调用工具类获取新IP ②记录下字符串中的页码;
  4. 然后用新IP和当前页码再次调用爬虫方法crawler( )继续爬虫。

下面是用ChatGPT进行的一个上述思路的总结(如果觉得上面的大段字看着费劲,可以参考下面的🐶):

A.爬虫方法 crawler( ) 的实现要求:

方法功能

  • 方法名称:crawler( )
  • 参数:int 类型的页码。
  • 返回值:String 类型,表示爬虫状态。

执行逻辑

  • 核心功能:尝试爬取指定页码的数据。
  • 成功时:如果爬取成功,返回 "success"
  • 异常处理:使用 try-catch 包裹爬虫核心代码,捕捉可能出现的异常。捕获到异常后,调用工具类的 checkIpAddress( ) 方法,检查当前代理 IP 是否有效。
  1. 如果当前 IP 无效:可能因 IP 失效导致爬虫中断,返回一个 JSON 格式的字符串,其中包含:中断时的 关键字、中断时的 页码
  2. 如果当前 IP 有效:
    说明异常不是因 IP 失效引起的,此时需手动抛出“爬虫异常”。
    手动抛出的异常应包含自定义的异常信息。

B.调用 crawler( ) 方法的主逻辑:

调用 crawler( ) 方法后,接收其返回的字符串 str

检查返回值str

  • 如果 str == "success":表示本次爬虫成功,无需进一步操作。
  • 如果 str 不是 "success"
    • 使用 JSON.isValid( ) 方法解析该字符串。
    • 若解析成功则表示代理ip失效需要更换新的 IP。
      1. 执行以下步骤:① 获取新代理 IP:调用工具类获取新的代理 IP。
                                ② 记录页码:从 str 中提取中断时的页码。
      2. 使用新 IP 和记录的页码,重新调用 crawler( ) 方法,继续执行爬虫。

循环上述过程,直到爬虫任务完成。

五、代码中的亮点:

以下是工具类代码中使用的一些亮点技术:


1. 线程安全的集合类:CopyOnWriteArraySet

  • 特点CopyOnWriteArraySet 是基于 CopyOnWriteArrayList 实现的线程安全集合,适合在多线程环境下需要频繁读取且写操作较少的场景。

  • 应用:用于存储代理 IP,保证在多线程操作时不出现并发问题。

  • 亮点:通过 removeIf 方法移除无效 IP,实现高效、安全的集合操作。


2. 多线程并发操作

  • 线程池使用:通过 Executors.newFixedThreadPool(10) 创建固定大小的线程池。

  • 目的:并发执行代理 IP 的可用性检查,提高程序执行效率。

  • 亮点

    • 避免每次创建和销毁线程的开销,提升性能。

    • 子线程的检查操作不会阻塞主线程,从而使抓取和检查 IP 可以并发进行。


3. 动态更新代理 IP 池

  • 逻辑:updateIpSet()

    方法会定期更新 IP 池:

    • 删除无效 IP。

    • 当 IP 池为空时,自动调用 getIpList 方法获取新的代理 IP。

  • 亮点:

    • 保证了代理 IP 池的有效性,避免程序因代理失效而中断。

    • 自动化管理 IP 池,减少了人工干预的需求。


4. JSON 数据解析

  • 工具:使用 fastjson2 解析 JSON 数据。

  • 功能:

    • 从代理 IP 提供商的 API 返回结果中提取 IP 地址和端口。

    • 动态构造 AgencyIp 对象,并添加到代理 IP 池中。

  • 亮点fastjson2 提供了高效、简洁的 JSON 解析方式,适合处理复杂数据结构。


5. 动态代理ip的网络连接检查

  • 技术:通过 Proxy 类创建 HTTP 动态代理,并使用 HttpURLConnection 检查代理 IP 的可用性。

  • 亮点:

    • 使用 Proxy.Type.HTTP 动态指定代理服务器和端口。

    • 设置连接超时和读取超时,防止长时间阻塞。

    • 支持多次重试机制,提高代理验证的鲁棒性。


6. 可扩展的代理 IP 池管理逻辑

  • 结构设计:

    • getAvailableIp 方法封装了获取有效 IP 的逻辑,确保返回的 IP 一定有效。

    • checkIpAddress 方法独立负责代理 IP 的可用性检查,职责清晰。

    • getIpList 方法负责动态从 API 获取新的代理 IP。

  • 亮点:模块化设计,代码清晰且易于扩展,便于日后维护和功能拓展。


7. 异常处理机制

  • 重试机制:在 checkIpAddress 方法中,加入了重试逻辑,当某次检查失败时会进行多次尝试。

  • 故障恢复:当抓取 IP 或检查 IP 时发生异常,提供了详细的日志信息,有助于问题排查。

  • 亮点:通过异常捕获和日志记录,使程序更稳定、可靠。


8. 自动化与高效性

  • 亮点:

    • 自动化抓取和更新代理 IP,减少了手动操作。

    • 结合多线程和动态代理技术,提升了执行效率。


总结

代码通过线程安全集合、多线程处理、动态代理、JSON 数据解析等技术,高效实现了一个可靠的代理 IP 池管理工具。代码模块化清晰,具有良好的扩展性和稳定性,非常适合在分布式爬虫或高并发网络请求场景中应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2265999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 数据库优化详解【Java数据库调优】

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

工业大数据分析算法实战-day15

文章目录 day15特定数据类型的算法工业分析中的数据预处理工况划分数据缺失时间数据不连续强噪声大惯性系统趋势项消除 day15 今天是第15天&#xff0c;昨日是针对最优化算法、规则推理算法、系统辨识算法进行了阐述&#xff0c;今日主要是针对其他算法中的特定数据类型的算法…

定时任务——定时任务技术选型

摘要 本文深入探讨了定时任务调度系统的核心问题、技术选型&#xff0c;并对Quartz、Elastic-Job、XXL-Job、Spring Task/ScheduledExecutor、Apache Airflow和Kubernetes CronJob等开源定时任务框架进行了比较分析&#xff0c;包括它们的特点、适用场景和技术栈。文章还讨论了…

前端遇见AI:打造智能应用的新时代

随着技术的发展&#xff0c;AI&#xff08;人工智能&#xff09;不再局限于后端服务器上运行的复杂算法&#xff0c;而是逐渐渗透到前端领域&#xff0c;成为提升用户体验和应用智能水平的关键因素。本文将探讨前端与AI结合的趋势&#xff0c;以及如何利用前端技术实现AI功能&a…

KNN分类算法 HNUST【数据分析技术】(2025)

1.理论知识 KNN&#xff08;K-Nearest Neighbor&#xff09;算法是机器学习算法中最基础、最简单的算法之一。它既能用于分类&#xff0c;也能用于回归。KNN通过测量不同特征值之间的距离来进行分类。 KNN算法的思想&#xff1a; 对于任意n维输入向量&#xff0c;分别对应于特征…

使用 Three.js 创建一个 3D 人形机器人仿真系统

引言 在这篇文章中&#xff0c;我们将探讨如何使用 Three.js 创建一个简单但有趣的 3D 人形机器人仿真系统。这个机器人可以通过键盘控制进行行走和转向&#xff0c;并具有基本的动画效果。 技术栈 HTML5Three.jsJavaScript 实现步骤 1. 基础设置 首先&#xff0c;我们需要…

Android unitTest 单元测试用例编写(初始)

文章目录 了解测试相关库导入依赖库新建测试文件示例执行查看结果网页结果其他 本片讲解的重点是unitTest&#xff0c;而不是androidTest哦 了解测试相关库 androidx.compose.ui:ui-test-junit4: 用于Compose UI的JUnit 4测试库。 它提供了测试Compose UI组件的工具和API。 and…

【蓝桥杯——物联网设计与开发】拓展模块3 - 温度传感器模块

目录 一、温度传感器模块 &#xff08;1&#xff09;资源介绍 &#x1f505;原理图 &#x1f505;STS30-DIS-B &#x1f319;引脚分配 &#x1f319;通信 &#x1f319;时钟拉伸&#xff08;Clock Stretching&#xff09; &#x1f319;单次触发模式 &#x1f319;温度数据转…

如何在任何地方随时使用本地Jupyter Notebook无需公网IP

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 今天就来给大家安利一套神器组合&#xff1a;通过Windows系统本地部…

长沙景区数据分析项目实现

一、设计题目 长沙景区数据分析项目 二、设计目的 通过本项目让学生独立完成数据统计、数据可视化、数据分析的过程&#xff0c;并提高学生解决问题的能力。 三、设计要求 读取‘长沙景区信息.xlsx’文件&#xff08;读取Excel文件的方法为pandas.read_excel()&#xff0c…

Kafka可视化工具 Offset Explorer (以前叫Kafka Tool)

数据的存储是基于 主题&#xff08;Topic&#xff09; 和 分区&#xff08;Partition&#xff09; 的 Kafka是一个高可靠性的分布式消息系统&#xff0c;广泛应用于大规模数据处理和实时, 为了更方便地管理和监控Kafka集群&#xff0c;开发人员和运维人员经常需要使用可视化工具…

PHP后执行php.exe -v命令报错并给出解决方案

文章目录 一、执行php.exe -v命令报错解决方案 一、执行php.exe -v命令报错 -PHP Warning: ‘C:\windows\SYSTEM32\VCRUNTIME140.dll’ 14.38 is not compatible with this PHP build linked with 14.41 in Unknown on line 0 解决方案 当使用PHP8.4.1时遇到VCRUNTIME140.dll…

详解MySQL在Windows上的安装

目录 查看电脑上是否安装了MySQL 下载安装MySQL 打开MySQL官网&#xff0c;找到DOWNLOADS 然后往下翻&#xff0c;找到MySQL Community(GPL) Downloads>> 然后找到MySQL Community Server 然后下载&#xff0c;选择No thanks,just start my download. 然后双击进行…

Excel粘贴复制不完整的原因以及解决方法

在数据处理和分析的过程中&#xff0c;Excel无疑是不可或缺的工具。然而&#xff0c;在使用Excel进行复制粘贴操作时&#xff0c;有时会遇到粘贴不完整的情况&#xff0c;这可能会让人感到困惑和烦恼。本文将深入探讨Excel粘贴复制不完整的原因、提供解决方案&#xff0c;并给出…

嵌入式轻量级开源操作系统:HeliOS的使用

嵌入式轻量级开源操作系统:HeliOS的使用 &#x1f4cd;项目地址&#xff1a;https://github.com/heliosproj/HeliOS HeliOS项目是一个社区交付的开源项目&#xff0c;用于构建和维护HeliOS嵌入式操作系统&#xff08;OS&#xff09;。HeliOS是一个功能齐全的操作系统&#xff0…

Linux复习3——管理文件系统2

修改文件权限命令 chmod 功能&#xff1a; chmod 命令主要用于修改文件或者目录的权限 只有文件所有者和超级用户可以修改文件或目录的权限 (1)使用数字表示法修改权限 所谓数字表示法是指将读取(r)、写入(w)和执行(x)分别以4、2、1来表示&#xff0c;没有授予的部分就表示…

ECharts散点图-气泡图,附视频讲解与代码下载

引言&#xff1a; ECharts散点图是一种常见的数据可视化图表类型&#xff0c;它通过在二维坐标系或其它坐标系中绘制散乱的点来展示数据之间的关系。本文将详细介绍如何使用ECharts库实现一个散点图&#xff0c;包括图表效果预览、视频讲解及代码下载&#xff0c;让你轻松掌握…

嵌入式驱动开发详解21(网络驱动开发)

文章目录 前言以太网框架ENET 接口简介MAC接口MII \ RMII 接口MDIO 接口RJ45 接口 PHY芯片以太网驱动驱动挂载wifi模块挂载后续 前言 linux驱动主要是字符设备驱动、块设备驱动还有网络设备驱动、字符设备驱动在本专栏前面已经详细将解了&#xff0c;网络设备驱动本文会做简要…

论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 王志豪&#xff0c;厦门大学博士生 刘诗雨&#xff0c;厦门大学硕士生 内容简介 新数据的不断涌现使版本更新成为大型语言模型&#xff08;LLMs&#xff…

FFmpeg 的常用API

FFmpeg 的常用API 附录&#xff1a;FFmpeg库介绍 库介绍libavcodec音视频编解码核心库编码 (avcodec_send_frame, avcodec_receive_packet)。解码 (avcodec_send_packet, avcodec_receive_frame)。libavformat提供了音视频流的解析和封装功能&#xff0c;多种多媒体封装格式&…