Java中使用四葉天動態代理IP構建ip代理池,實現httpClient和Jsoup代理ip爬蟲

在本次爬蟲項目中,關于應用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 {//使用線程安全集合類存儲代理ipprivate 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()) {//刪除無效ipipSet.removeIf(ip -> !checkIpAddress(ip));}
?if (ipSet.isEmpty()) {//如果空,則獲取ipgetIpList();}}
?//抓取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();//關閉BufferedReaderconn.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;
?// 要訪問的目標 URLString targetUrl = "https://www.baidu.com";
?try {// 配置 Jsoup 使用代理 IPDocument 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;
?// 要訪問的目標 URLString 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.pswp.cn/web/63796.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/63796.shtml
英文地址,請注明出處:http://en.pswp.cn/web/63796.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CEF127 編譯指南 MacOS 篇 - 拉取 CEF 源碼(五)

1. 引言 在完成了所有必要工具的安裝和配置后&#xff0c;我們進入到獲取 CEF 源碼的階段。對于 macOS 平臺&#xff0c;CEF 的源碼獲取過程需要特別注意不同芯片架構&#xff08;Intel 和 Apple Silicon&#xff09;的區別以及版本管理。本文將詳細介紹如何在 macOS 系統上獲…

梳理你的思路(從OOP到架構設計)_設計模式Factory Method模式

目錄 1、Factory Method模式 2、范例&#xff1a; Android FM(工廠)模式 3、Android里處處可見的FM模式的應用 1、Factory Method模式 誰來創建<T>的對象呢?例如&#xff0c; 剛才的Template Method模式內含一個EIT造形&#xff0c;那麼&#xff0c; 請問&#xff…

tauri桌面應用開發入門

簡介 tauri是一款基于web的桌面應用前端框架 因為使用webviews渲染,而不是像electron自帶一個瀏覽器內核,所以打包之后的空間更小,十幾mb 前端界面使用web,可以采取流行的框架,入react,vue等 前端后臺采用rust,彌補前端無法直接訪問操作系統,常用于訪問本地文件系統 官方中…

selenium 報錯 invalid argument: invalid locator

環境&#xff1a; Python3.12.2 selenium4.0 報錯信息&#xff1a; invalid argument: invalid locator 錯誤分析&#xff1a; selenium語法錯誤,find_element方法少寫By.XPATH參數 錯誤語法如下&#xff1a; driver.find_element(//div[id"myid"]) 解決辦…

ESP8266 WiFi模塊入門:搭建網絡與測試實踐

在物聯網&#xff08;IoT&#xff09;應用中&#xff0c;設備聯網是核心功能之一。而ESP8266串口WiFi ESP-01模塊是一款低成本、功能強大的UART-WiFi透傳模塊&#xff0c;廣泛應用于智能家居、工業控制等領域。本篇文章將從基礎出發&#xff0c;講解如何使用ESP8266模塊進行WiF…

框架問題學習

1、gin 1.1、gin框架路由是怎么處理的 在 Gin 中&#xff0c;路由是通過 gin.Default() 或 gin.New() 創建的 *gin.Engine 對象來管理的。gin.Default() 是 gin.New() 的一個封裝&#xff0c;它在創建路由對象時會自動添加一個默認的中間件&#xff08;如日志記錄、恢復中間件…

Java模擬Mqtt客戶端連接Mqtt Broker

Java模擬Mqtt客戶端基本流程 引入Paho MQTT客戶端庫 <dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.mqttv5.client</artifactId><version>1.2.5</version> </dependency>設置mqtt配置數據 …

電子電氣架構 --- 隊列刷寫場景及刷寫上位機淺析

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 所謂雞湯,要么蠱惑你認命,要么慫恿你拼命,但都是回避問題的根源,以現象替代邏輯,以情緒代替思考,把消極接受現實的懦弱,偽裝成樂觀面對不幸的…

springboot根據租戶id動態指定數據源

代碼地址 碼云地址springboot根據租戶id動態指定數據源: springboot根據租戶id指定動態數據源,結合mybatismysql多數源下的事務管理 創建3個數據庫和對應的表 sql腳本在下圖位置 代碼的執行順序 先設置主數據庫的數據源配置目標數據源和默認數據源有了主庫的數據源&#xff…

C++簡明教程(文章要求學過一點C語言)(3)

一、編程工具大揭秘——IDE 當我們準備踏入 C 編程的奇妙世界時&#xff0c;首先要認識一個重要的“魔法盒子”——集成開發環境&#xff08;IDE&#xff09;。IDE 就像是一個全能的編程工作室&#xff0c;它把我們寫代碼所需要的各種工具都整合到了一起&#xff0c;讓編程這件…

達夢官方工具 SQLark數據遷移(oracle->達夢數據庫)

應國產化需求需要,需將系統中涉及的各中間件替換成國產中間件,此文介紹了從Oracle遷移數據至達夢dm8的步驟,該文在windos環境下已驗證測試過 1 SQLark介紹 SQLark是一款專為信創應用開發者設計的數據庫開發和管理工具。它支持快速查詢、創建和管理多種類型的數據庫系統&#xf…

【JAVA】JAVA接口公共返回體ResponseData封裝

一、JAVA接口公共返回體ResponseData封裝&#xff0c;使用泛型的經典 例子 public class ResponseData<T> implements Serializable { /** * */ private static final long serialVersionUID 7098362967623367826L; /** * 響應狀態碼 */ …

AlipayHK支付寶HK接入-商戶收款(PHP)

一打開支付寶國際版 二、點開商戶服務 三、下載源碼

【Prompt Engineering】6 文本擴展

一、引言 文本擴展&#xff1a;將短文本輸入到大型語言模型中&#xff0c;生成更長的文本。應用場景&#xff1a;頭腦風暴、生成電子郵件或論文等。風險&#xff1a;可能被用于生成垃圾郵件。使用原則&#xff1a;負責任地使用&#xff0c;確保有益于人們。技術準備&#xff1…

nginx學習總結(不包含安裝過程)

1. nginx常見配置 http服務上支持【若干虛擬主機】。每個虛擬主機對應一個server配置項&#xff0c;配置項里面包含該虛擬主機相關的配置。 server{listen 80 default;server_name www.yonqin.com;index index.html index.htm index.php;root /data/www;location ~ .*\.(gif|…

CSS系列(29)-- Scroll Snap詳解

前端技術探索系列&#xff1a;CSS Scroll Snap詳解 &#x1f4dc; 致讀者&#xff1a;探索流暢滾動體驗 &#x1f44b; 前端開發者們&#xff0c; 今天我們將深入探討 CSS Scroll Snap&#xff0c;這個強大的滾動優化特性。 基礎特性 &#x1f680; 容器設置 /* 基礎滾動…

如何設計高效的商品系統并提升擴展性:從架構到實踐的全方位探索

在現代電商、零售及企業資源管理系統中&#xff0c;商品管理無疑是核心模塊之一。隨著市場的變化與企業規模的擴展&#xff0c;商品系統需要具備強大的功能支持以及高效的擴展能力&#xff0c;以應對日益復雜的業務需求。一個設計良好的商品系統不僅僅是一個商品信息的容器&…

RFdiffusion get_torsions函數解讀

函數功能 get_torsions 函數根據輸入的原子坐標(xyz_in)和氨基酸序列(seq),計算一組主鏈和側鏈的扭轉角(torsions)。同時生成備用扭轉角(torsions_alt),用于表示可以鏡像翻轉的幾何結構,并返回掩碼(tors_mask)和是否平面化(tors_planar)的信息。 輸入參數 xyz…

docker springboot 運維部署詳細實例

環境安裝 [rootiZbp1dcnzq7pzpg9607m6pZ ~]# docker -v Docker version 26.1.4, build 5650f9b鏡像構建 Dockerfile 文件內容 FROM openjdk:8 # Author Info 創建人信息 MAINTAINER ratelcloudfoxmail.com ENV PORT20001 EXPOSE 20001 RUN mkdir /usr/local/ratel-boot-serv…

貪心算法在背包問題上的運用(Python)

背包問題 有n個物品,它們有各自的體積和價值,現有給定容量的背包,如何讓背包里裝入的物品具有最大的價值總和? 這就是典型的背包問題(又稱為0-1背包問題),也是具體的、沒有經過任何延伸的背包問題模型。 背包問題的傳統求解方法較為復雜,現定義有一個可以載重為8kg的背…