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

Python(十九)实现各大跨境船公司物流查询数据处理优化

一、前言

之前已经实现了常用 跨境物流船司 基础信息查询功能,如下所示

  • 实现各大跨境船公司[COSCO/ZIM/MSK/MSC/ONE/PIL]的物流信息查询:
  • https://blog.csdn.net/Makasa/article/details/145484999?spm=1001.2014.3001.5501

然后本章在其基础上做了一些优化,以及新增之前未实现的功能

1)实现【提单号】单个自动分配查询船司信息

  • 方法:assign_shipper(bill_number)

2)实现【提单号】批量查询

  • 方法:search_tracking_info_by_list(bl_list)

3)获取最新【ETA(预计到港时间)】时间并自动写入excel

  • 方法:get_latest_eta_time_and_insert_excel()

会在原有excel文件中原【ETA】列后添加一行,再将新的【ETA】填写进去
不直接替换原因便于对比;在这里插入图片描述

4)自动将船司查询到的信息按规定表头写入excel表格【单条】

  • insert_ship_detail_to_excel(“NGZN50041300”)
  • 注意:表头格式我这边按实际需求限定死了,可以按你们自己需求进行更改

在这里插入图片描述
在这里插入图片描述

5)批量将船司查询到的信息按规定表头写入excel表格【list】

  • insert_ship_detail_list_to_excel(bl_list) # 批量插入数excel数据

未来需优化:

  • 1)PIL船司返回的前端,解析目前还存在一点问题,需要兼容各种返回情况的产生;
    目前默认只解析拿到第一个集装箱的数据;
  • 2)ZIM接口不稳定,需排查问题
  • 3)OOCL / CMA /HPL 加密 尝试找方法破解


二、代码实现

  • 上篇blog已经实现了基础查询功能,按船司分开写的,这里我就不统一分开了,直接贴整个代码
# -*- codeing = utf-8 -*-
# @time: 2025/2/12  14:26
# @Author : Mikasaimport json
import time
from datetime import datetime
import pandas as pd
import requests
from bs4 import BeautifulSoup
from pathlib import Pathdef get_MSK_tracking_info(tracking_number):"""查询MSK船司物流信息:param tracking_number:提单号:return:"""url = "https://api.maersk.com.cn/synergy/tracking/" + tracking_numberparams = {"operator": "MAEU"}headers = {"consumer-key": "UtMm6JCDcGTnMGErNGvS2B98kt1Wl25H",  # 关键认证头 必传"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36"}try:response = requests.get(url, params=params, headers=headers, timeout=10)result_json = response.json()print("===========================================")print("MSK船信息:", result_json)return result_jsonexcept requests.exceptions.RequestException as e:print(f"请求失败: {e}")except json.JSONDecodeError:print("响应不是有效的 JSON 格式")def get_MSK_related_time(tracking_number):"""获取MSK船期时间:param tracking_number::return:"""result = get_MSK_tracking_info(tracking_number)location_list = result['containers'][0]['locations']target_terminal = "APAPA PORT"index = 0for i, location in enumerate(location_list):if location["terminal"] == target_terminal:index = i  # 拿到目的地为apapa PORT的数据的indexbreak# todo : 246217454 这个已经到港并且已经完结的提单没有expected_time属性# todo :248440101 未到港,就存在expected_time属性ship_info = location_list[index]['events'][0]event_time_type = ship_info['event_time_type']if event_time_type == "EXPECTED":# 提单还未到港ETA = ship_info['expected_time']elif event_time_type == "ACTUAL":# 提单已到港,拿真实时间ETA = ship_info['actual_time']new_ETA_fomat = deal_MSK_eta_time_format(ETA)print("------------------------------------------")print(f"提单号【{tracking_number}】船期信息如下:")print(f"预计到港时间:{new_ETA_fomat}")return new_ETA_fomatdef deal_MSK_eta_time_format(date):"""处理MSK船司预期时间格式:param date::return:"""dt = datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%f")formatted_str = dt.strftime("%Y/%#m/%#d %H:%M:%S")return formatted_strdef get_ONE_tracking_info_by_bill_number(bill_number):"""根据提单号查询ONE物流信息:param bill_number::return:"""str = "ONEY"if str in bill_number:bill_number = bill_number.replace("ONEY", "")headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36","Content-Type": "application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With": "XMLHttpRequest"}url = "https://ecomm.one-line.com/ecom/CUP_HOM_3301GS.do?" \"sord=asc" \"&f_cmd=121" \"&search_type=B" \f"&search_name={bill_number}"response = requests.get(url, headers=headers)result = response.json()print("BL_response:", result)return resultdef get_ONE_tracking_info(bill_number):"""查询ONE船司物流信息:param tracking_number::return:"""result = get_ONE_tracking_info_by_bill_number(bill_number)container_list = result['list'][0]  # 默认取第一个集装箱container_number = container_list['cntrNo']cop_no = container_list['copNo']bkg_no = container_list['bkgNo']url = "https://ecomm.one-line.com/ecom/CUP_HOM_3301GS.do"headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36","Content-Type": "application/x-www-form-urlencoded; charset=UTF-8","X-Requested-With": "XMLHttpRequest"}payload = {"f_cmd": "125","cntr_no": container_number,"bkg_no": bkg_no,"cop_no": cop_no}response = requests.post(url, headers=headers, data=payload)if response.status_code == 200:data = response.json()print("===========================================")print("ONE船信息:", response.json())return datadef get_ONE_related_time(bill_number):"""查询ONE船期时间:param bill_number::return:"""data = get_ONE_tracking_info(bill_number)track_info_list = data['list']eta = "Arrival at Port of Discharging"actual_pod = "POD Berthing Destination"discharge_cargo = "Port of Discharging"print("------------------------------------------")print(f"提单号【{bill_number}】船期信息如下:")for track_info in track_info_list:statusNm = track_info['statusNm']if eta in statusNm:print(f"预期到港时间:", track_info['eventDt'])elif actual_pod in statusNm:print(f"实际抵达卸货港时间:", track_info['eventDt'])elif discharge_cargo in statusNm:print(f"实际卸货时间:", track_info['eventDt'])return track_info['eventDt']  # 直接返回的最新一套信息的时间def get_PIL_cookie():"""获取PIL的cookie:return:"""# 生成北京当前时间戳 单位为mstimestamp_ms = int(time.time() * 1000)url = "https://www.pilship.com/wp-content/themes/hello-theme-child-master/pil-api/common/get-n.php?timestamp=" + str(timestamp_ms)headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36","Referer": "https://www.pilship.com/digital-solutions/?tab=customer&id=track-trace&label=containerTandT&module=TrackTraceBL&refNo=NGRI50097000"}response = requests.get(url, headers=headers)return responsedef get_PIL_tracking_info_by_bill_number(bill_number):"""根据提单号查询PIL物流信息:param bill_number::return:"""response = get_PIL_cookie()  # 拿到nn = response.json()['n']timestamp = str(int(time.time() * 1000))referer = "https://www.pilship.com/digital-solutions/?tab=customer&id=track-trace&label=containerTandT&module=TrackTraceBL&refNo=" + bill_numberheaders = {'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",'referer': referer,'X-Requested-With': "XMLHttpRequest",'cookie': "CookieConsent={stamp:%27LUQ2eOuWASANePCHNSXS2yeSAiOmJoQhXm7pEbeVpMEr7kRRRhczfw==%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cmethod:%27explicit%27%2Cver:1%2Cutc:1734771385816%2Cregion:%27ng%27}; _ga=GA1.1.1137581632.1734770854; pil_session_cookie=!WFtN5njOPpQS1hf8xTD27kmUREcR4A5xQFGbSdeZWh6xne7uf6cynXyQzICRX7DAVtXpZHsVQFbXaA==; wp-wpml_current_language=en; TSPD_101=08c4718e7dab2800c57f82cee5e846814246783a4ea9308f585af084e53e57c851f4d7af7507b6ba01b43d68d07a6fc9084f292334051800b0bdc60b7433c56f989c7ca0dcd64b787093688cd95badc6; TS00000000076=08c4718e7dab28007707032a2a3c087717436b105e0ea27086f21be845e6238e426c659eed97e9faac24d9498ea8e2f90825bede2809d000f4ff876b60b5d60819d6e9be3e6f3d6f2d0ad9cc544d6ba809938284a1f852c824efa411a4094ef683ea56f2d383a67379539aa5b28a9a52823dde83af710cc1065a8cb738359c2102062f1f41799313cc887fe2f7f84015edf73a4443f90343838461044c8dbccae6660ca3322e787bb229d3ae25557ce32af1669c3ddeb451eb967fe99ac32cc0ef550af1567da52efbed7d17b811159ef5b40416eb7178abca86b4f273868b80aee1cd0ab7a38515f98e7b91baf133b22894982a220077e68b7c314d8ca5c0f89a4bbc55a09b538e; TSPD_101_DID=08c4718e7dab28007707032a2a3c087717436b105e0ea27086f21be845e6238e426c659eed97e9faac24d9498ea8e2f90825bede28063800dd525af8f96ac9cff1388ccc906e36023328029cfae4893759356223de54c62e94a0c306a33859e46108198cac5061a89c8fa7c14267e4fc; TS7ff733e9077=08c4718e7dab280085f60f04ba264a2e0ac0875b36b59c53defab055f5fea0c7c7ce7b40ed9afcf756781ecc450e1b470807626b7517200050d650fcfa6773405f5a17954cff4628d908f416f4234200dbaa3cc3ec46b52a; _ga_M39J8YZNDE=GS1.1.1738786704.56.0.1738786704.0.0.0; TS015cd57e=011698f8e78ca3bc42cad4dd0e721fdcb048e98d12c3529eecbcc961ce0855aa8b6eef2788cf1b3cc8bbe190c65fcf3d0666de4efd377ed9d22d0f951ed126bf67a554e95c; TS7ff733e9029=08c4718e7dab2800e6a5d0f6faeca1dc19685dfff567b4dd1369f1b4b696f84893905e24cb58bc50ffb1a716a0e029fa; TS97a2723b027=08c4718e7dab2000fd4b11416d6e7e1c3da097165f9bd7b084e973e022fa2ec9d671050f9f2f2966081a278b7c1130004fb6fbf91b1d6cb4cd98e6bcb7bd8410d5bed0a0f4b4e1e764e4f4d75f4d5666b6a1bb124f33758104b457ee4acaf2c2"}# 否则根据提单号查询url = f"https://www.pilship.com/wp-content/themes/hello-theme-child-master/pil-api/trackntrace-containertnt.php?" \f"module=TrackTraceBL" \f"&refNo={bill_number}" \f"&n={n}" \f"&timestamp={timestamp}"response = requests.get(url, headers=headers)print("url:", response.url)  # 查看最终请求的 URLif response.status_code == 200:response_json = json.loads(response.text)result_json = analysis_PIL_response_by_bill_number(response_json)  # 解析return result_jsonelse:print("通过【提单号】查询PIL船司信息失败")def get_PIL_tracking_info(bill_number):"""查询PIL船公司物流信息(完整工作流)- 包含动态Token获取和Cookie管理- 必传校验:n | 经过多次测试,发现cookie只穿"""response = get_PIL_cookie()  # 拿到nn = response.json()['n']timestamp = str(int(time.time() * 1000))referer = "https://www.pilship.com/digital-solutions/?tab=customer&id=track-trace&label=containerTandT&module=TrackTraceBL&refNo=" + bill_numberheaders = {'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",'referer': referer,'X-Requested-With': "XMLHttpRequest",'cookie': "CookieConsent={stamp:%27LUQ2eOuWASANePCHNSXS2yeSAiOmJoQhXm7pEbeVpMEr7kRRRhczfw==%27%2Cnecessary:true%2Cpreferences:true%2Cstatistics:true%2Cmarketing:true%2Cmethod:%27explicit%27%2Cver:1%2Cutc:1734771385816%2Cregion:%27ng%27}; _ga=GA1.1.1137581632.1734770854; pil_session_cookie=!WFtN5njOPpQS1hf8xTD27kmUREcR4A5xQFGbSdeZWh6xne7uf6cynXyQzICRX7DAVtXpZHsVQFbXaA==; wp-wpml_current_language=en; TSPD_101=08c4718e7dab2800c57f82cee5e846814246783a4ea9308f585af084e53e57c851f4d7af7507b6ba01b43d68d07a6fc9084f292334051800b0bdc60b7433c56f989c7ca0dcd64b787093688cd95badc6; TS00000000076=08c4718e7dab28007707032a2a3c087717436b105e0ea27086f21be845e6238e426c659eed97e9faac24d9498ea8e2f90825bede2809d000f4ff876b60b5d60819d6e9be3e6f3d6f2d0ad9cc544d6ba809938284a1f852c824efa411a4094ef683ea56f2d383a67379539aa5b28a9a52823dde83af710cc1065a8cb738359c2102062f1f41799313cc887fe2f7f84015edf73a4443f90343838461044c8dbccae6660ca3322e787bb229d3ae25557ce32af1669c3ddeb451eb967fe99ac32cc0ef550af1567da52efbed7d17b811159ef5b40416eb7178abca86b4f273868b80aee1cd0ab7a38515f98e7b91baf133b22894982a220077e68b7c314d8ca5c0f89a4bbc55a09b538e; TSPD_101_DID=08c4718e7dab28007707032a2a3c087717436b105e0ea27086f21be845e6238e426c659eed97e9faac24d9498ea8e2f90825bede28063800dd525af8f96ac9cff1388ccc906e36023328029cfae4893759356223de54c62e94a0c306a33859e46108198cac5061a89c8fa7c14267e4fc; TS7ff733e9077=08c4718e7dab280085f60f04ba264a2e0ac0875b36b59c53defab055f5fea0c7c7ce7b40ed9afcf756781ecc450e1b470807626b7517200050d650fcfa6773405f5a17954cff4628d908f416f4234200dbaa3cc3ec46b52a; _ga_M39J8YZNDE=GS1.1.1738786704.56.0.1738786704.0.0.0; TS015cd57e=011698f8e78ca3bc42cad4dd0e721fdcb048e98d12c3529eecbcc961ce0855aa8b6eef2788cf1b3cc8bbe190c65fcf3d0666de4efd377ed9d22d0f951ed126bf67a554e95c; TS7ff733e9029=08c4718e7dab2800e6a5d0f6faeca1dc19685dfff567b4dd1369f1b4b696f84893905e24cb58bc50ffb1a716a0e029fa; TS97a2723b027=08c4718e7dab2000fd4b11416d6e7e1c3da097165f9bd7b084e973e022fa2ec9d671050f9f2f2966081a278b7c1130004fb6fbf91b1d6cb4cd98e6bcb7bd8410d5bed0a0f4b4e1e764e4f4d75f4d5666b6a1bb124f33758104b457ee4acaf2c2"}result_json = get_PIL_tracking_info_by_bill_number(bill_number)container_number = result_json['data']['table2'][0]['Container #']container_number = container_number[:11]  # 截取固定bl固定长度11位print("container_number:", container_number)if container_number != '':# 箱号存在,就根据箱号查询url = f"https://www.pilship.com/wp-content/themes/hello-theme-child-master/pil-api/trackntrace-containertnt-trace.php?" \f"module=TrackTraceBL" \f"&reference_no={bill_number}" \f"&cntr_no={container_number}" \f"&n={n}" \f"&timestamp={timestamp}"response = requests.get(url, headers=headers)# print("url:", response.url)  # 查看最终请求的 URLif response.status_code == 200:response_json = json.loads(response.text)resule_json = analysis_PIL_response_by_container_number(response_json)  # 解析return resule_jsonelse:print("通过【箱号】查询PIL船司信息失败")def analysis_PIL_response_by_container_number(response_json):"""解析通过【提单号+箱号】查询PIL船信息response的前端属性:param bill_number::param container_number::return:"""html_data = response_json["data"]  # 提取data里的htmlsoup = BeautifulSoup(html_data, "html.parser")  # 解析# 提取表头header_row = soup.find("tr", class_="bg-lightblue text-fc-black text-fw-bold")headers = [th.text.strip() for th in header_row.find_all("td")]# 提取数据行data_rows = soup.find_all("tr", class_="bg-lightblue text-fc-black")table_data = []for row in data_rows:cells = row.find_all("td")row_data = {headers[i]: cells[i].text.strip() for i in range(len(headers))}table_data.append(row_data)# 构建最终的 JSON 结构result = {"success": response_json["success"],"data": table_data}return resultdef analysis_PIL_response_by_bill_number(response_json):"""解析通过【提单号】查询PIL船信息response的前端属性- 因为通过【提单号】/【箱号】返回的dom树结构不一样,所以解析方法不一致- 注意:解析不兼容,提单号里面没有箱号树的情况 例如:TAJM40625400:param bill_number::return:"""html_data = response_json["data"]  # 提取htmlsoup = BeautifulSoup(html_data, "html.parser")  # 解析 HTMLbl_number = soup.find("b").texttable1 = soup.find("table")table1_data = []headers = [th.text for th in table1.find("tr", class_="table-header").find_all("th")]rows = table1.find_all("tr", class_="resultrow")for row in rows:cells = row.find_all("td")row_data = {headers[i]: cells[i].get_text(separator=" ").strip() for i in range(len(headers))}table1_data.append(row_data)# 提取第二个表格的数据table2 = soup.find("table", class_="table")table2_data = []headers = [td.text for td in table2.find("thead").find_all("td")]rows = table2.find("tbody").find_all("tr")for row in rows:# todo: 解析还存在点问题 没有适配所有情况 例如: TAJM40625400 就报错cells = row.find_all("td")row_data = {headers[i]: cells[i].get_text(separator=" ").strip() for i in range(len(headers))}table2_data.append(row_data)# 构建最终的 JSON 结构result_json = {"success": response_json["success"],"data": {"bl_number": bl_number,"table1": table1_data,"table2": table2_data}}return result_jsondef get_PIL_related_time(bill_number):"""获取PIL船期时间- 传container_number 原因是为了得到dom树里面更具体的时间;- 只根据提单查询的话,container_number传空字符串'':param bill_number::param container_number::return:"""result_json = get_PIL_tracking_info(bill_number)print("result_json:", result_json)dom_list = result_json['data']for dom in dom_list:# 根据箱号查询的dom树jsonif dom['Event Name'] == "Vessel Discharge" and dom['Event Location'] == "LAGOS (APAPA SEAPORT)":new_eta_format = deal_PIL_eta_date_format(dom['Event Date'])print("------------------------------------------")print(f"提单号【{bill_number}】,船期信息如下:")print("预期到港时间:", new_eta_format)return new_eta_formatdef deal_PIL_eta_date_format(date_str):"""处理PIL日期格式: 将 18-Jan-2025 18:46:00 转化为 2025/1/18 18:46:00- 这里需要加个判断:因为根据箱号查询返回的日期前面会有个前缀,【* 】,我们需去除后再进行转换:param date_str::return:"""try:if "* " in date_str:date_str = date_str.lstrip("* ").strip()dt = datetime.strptime(date_str, "%d-%b-%Y %H:%M:%S")import platformif platform.system() == "Windows":formatted_date = dt.strftime("%Y/%#m/%#d %H:%M:%S")else:formatted_date = dt.strftime("%Y/%-m/%-d %H:%M:%S")return formatted_dateexcept ValueError as e:print("日期时间格式错误:", e)def get_ZIM_access_token():session = requests.session()api_url = "https://www.goldstarline.com/#/track_ship"session.get(api_url)cookies_dict = session.cookies.get_dict()headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36','cookie': "; ".join([f"{k}={v}" for k, v in cookies_dict.items()]),}payload = {'country_code': 'HK'}url = "https://www.goldstarline.com/react-rest//access_token"response = session.post(url, data=payload, headers=headers)return responsedef get_ZIM_tracking_info(tracking_number):"""获取ZIM船司物流信息:param tracking_number:提单号权限校验:必传cookie & authorization- 格式:Bearer 52851984- ZIM接口经常不稳定,当一次调用不成功,可重复再调用即可:return:"""# todo: GOSUNGB20416758 bug调试access_response = get_ZIM_access_token()time.sleep(1)token = access_response.json()['token']cookie = access_response.cookies.get_dict()['ci_session']cookie = "ci_session=" + cookie + ";"authorization = "Bearer " + token# print("cookie:", cookie)# print("authorization:", authorization)session = requests.Session()api_url = "https://www.goldstarline.com/#/track_shipment"session.get(api_url)url = "https://www.goldstarline.com/react-rest//get_track_shipment_val"payload = {"containerid": tracking_number}# cookie 通过测试,只需要拿到ci_session即可headers = {'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",'Content-Type': "application/x-www-form-urlencoded",'cookie': cookie,'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",'authorization': authorization,'accept': "application/json, text/plain, */*",'Cache-Control': "no-cache",}try:response = session.request("POST", url, data=payload, headers=headers)if response.status_code == 200:data = response.json()print("===========================================")print("ZIM船信息:", data)if data['status'] == '0':print("请检查Cookie或authorization是否有效")returnreturn dataelse:print("请求失败,请重新再试")except requests.exceptions.RequestException as e:return f"请求错误: {str(e)}"def deal_ZIM_eta_time_format(date):"""处理ZIM船司ETA时间格式- 将 04-Mar-2025 转换为 2025/3/4:param date::return:"""dt = datetime.strptime(date, "%d-%b-%Y")formatted_date = f"{dt.year}/{dt.month}/{dt.day}"return formatted_datedef get_ZIM_related_time(tracking_number):"""获取ZIM相关船期时间通过观察ZIM查询逻辑: 如果POD里面获取不到值就去取arrivalDateTz - dateTime我们加一层判断:param tracking_number::return:"""data = get_ZIM_tracking_info(tracking_number)try:if data['status'] == '0':print("ZIM船司-提单号查询返回数据为空,请检查提单号是否有误,或者船司还未同步更新")else:estimated_time_of_arrival = data['message']['pod']['estimated_time_of_arrival']if estimated_time_of_arrival == '':arrivalDateTz = data['message']['response']['blRouteLegs'][0]['arrivalDateTz']['dateTime']print("------------------------------------------")print(f"提单号【{tracking_number}】的船期信息如下:")print("预计到港时间:", arrivalDateTz)return arrivalDateTzelse:new_eta_format = deal_ZIM_eta_time_format(estimated_time_of_arrival)print("------------------------------------------")print(f"提单号【{tracking_number}】的船期信息如下:")print("预计到港时间:", new_eta_format)return new_eta_formatexcept requests.exceptions.RequestException as e:return f"请求数据失败: {str(e)}"def get_MSC_tracking_info(tracking_number):"""查询MSC船公司信息:param tracking_number: 提单号/预约号:param tracking_number: 为0根据提单号查询;为1根据预约号查询这里后端直接加个判断:如果传进来的tracking_number的前面4位数不以[MEDU]开头则为置为1;否则默认为0:return: 具体船期时间"""session = requests.Session()api_url = "https://www.msc.com/api/feature/tools/TrackingInfo"headers = {"Content-Type": "application/json","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36","X-Requested-With": "XMLHttpRequest",}if tracking_number[:4] == "MEDU":tracking_mode = "0"  # 提单号查询else:tracking_mode = "1"  # 预约号查询payload = {"trackingNumber": tracking_number,"trackingMode": tracking_mode}try:response = session.post(api_url, json=payload, headers=headers)if response.status_code == 200:data = response.json()print("===========================================")print("MSC船信息:", data)return dataexcept requests.exceptions.RequestException as e:return f"请求错误: {str(e)}"def deal_MSC_ETA_date_format(date):""":param Pod_eta_date: MSC返回日期为15/02/2025 转为2025/2/15:return:"""date_obj = datetime.strptime(date, "%d/%m/%Y")new_date_str = date_obj.strftime("%Y/%m/%d")return new_date_strdef get_MSC_related_time(tracking_number):"""根据单号获取MSC相关时间:param tracking_number: 提单号/预约号:return:"""data = get_MSC_tracking_info(tracking_number)if data is not None:# time.sleep(5)actualShipment_info = data['Data']['BillOfLadings'][0]['ContainersInfo']print("actualShipment_info:", actualShipment_info)PodEtaDate = actualShipment_info[0]['PodEtaDate']if PodEtaDate == '':# 若ETA为空,则输出最近一条物流消息print("===========================================")print(f"该提单【{tracking_number}】目前暂无ETA信息")latest_event = actualShipment_info[0]['Events'][0]  # MSC是倒序的,所以取第一条date = latest_event['Date']PodEtaDate = deal_MSC_ETA_date_format(date)  # 日期格式转换EquipmentHandling = latest_event['EquipmentHandling']['Name']print(f"其最新一条物流消息如下:\n日期:{PodEtaDate},位于 {EquipmentHandling};")else:PodEtaDate = deal_MSC_ETA_date_format(PodEtaDate)  # 日期格式转换print("------------------------------------------")print(f"提单号【{tracking_number}】的船期信息如下:")print("预计到港时间:", PodEtaDate)return PodEtaDateelse:print("请求存在延迟,返回数据为None,需要再次调用")def get_COSCO_tracking_info(tracking_number):"""根据提单号查询COSCO船司物流信息:param bill_of_lading: 目前只能根据提单号查询;预约号无法查询到:return: 返回"""tracking_number = deal_COSCO_bill_number(tracking_number)  # 处理前缀COSUsession = requests.Session()headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36","Accept": "application/json","X-Requested-With": "XMLHttpRequest"}try:# 假设发现的API端点(需要实际分析)api_url = f"https://elines.coscoshipping.com/ebtracking/public/bill/{tracking_number}"print("api_url:", api_url)response = session.get(api_url, headers=headers)if response.status_code == 200:data = response.json()print("===========================================")print("COSCO船信息:", data)return dataelse:print("COSCO船信息查询失败")print("错误返回:", response)returnexcept Exception as e:return f"请求失败: {str(e)}"def deal_COSCO_bill_number(bill_number):"""处理COSCO提单号:COSU6407335642 过滤掉单号前4位前缀因为COSCO只能根据数值查询,添加了前缀无法查询:param bill_number: 提单号:return:"""remove_substring = "COSU"if remove_substring in bill_number:new_bill_number = bill_number.replace(remove_substring, "")else:new_bill_number = bill_numberreturn new_bill_numberdef get_COSCO_related_time(tracking_number):"""获取COSCO单号相关时间:param tracking_number: 提单号:return:"""data = get_COSCO_tracking_info(tracking_number)# COSCO查询逻辑actualShipment_list = data['data']['content']['actualShipment']print("actualShipment_list:", actualShipment_list)len_actualShipment_list = len(actualShipment_list)if len_actualShipment_list == 0:# 若里面只有一条数据,就取这里面的第一条actualShipment_info = actualShipment_list[0]print("actualShipment_info:", actualShipment_info)estimatedDateOfArrival = actualShipment_info['estimatedDateOfArrival']actualArrivalDate = actualShipment_info['actualArrivalDate']actualDischargeDate = actualShipment_info['actualDischargeDate']else:# 否则取list中最后条数据actualShipment_info = actualShipment_list[len_actualShipment_list - 1]print("actualShipment_info:", actualShipment_info)estimatedDateOfArrival = actualShipment_info['estimatedDateOfArrival']actualArrivalDate = actualShipment_info['actualArrivalDate']actualDischargeDate = actualShipment_info['actualDischargeDate']print("------------------------------------------")print(f"提单号【{tracking_number}】的船期信息如下:")print("预计到港时间:", estimatedDateOfArrival)print("实际到港时间:", actualArrivalDate)print("实际卸货时间:", actualDischargeDate)return estimatedDateOfArrival# todo : COSCO船司网站崩了
# get_COSCO_tracking_info("COSU6407335642")def assign_shipper(tracking_number):"""分配对应公司查询 COSCO | ZIM | MSK | MSC | ONE | PIL- 使用前缀判断:param tracking_number::return:"""if type(tracking_number) != "str":tracking_number = str(tracking_number)if "COSU" in tracking_number or tracking_number[0] == '6' or tracking_number[0] == '9':print("===========================================")print("【COSCO船司物流信息查询】")eta_time = get_COSCO_related_time(tracking_number)elif tracking_number[0] == '2':print("===========================================")print("【MSK船司物流信息查询】")eta_time = get_MSK_related_time(tracking_number)elif "GOSU" in tracking_number:print("===========================================")print("【ZIM船司物流信息查询】")eta_time = get_ZIM_related_time(tracking_number)elif "ONEY" in tracking_number:print("===========================================")print("【ONE船司物流信息查询】")eta_time = get_ONE_related_time(tracking_number)elif "MEDU" in tracking_number or tracking_number[0] == '1':print("===========================================")print("【MSC船司物流信息查询】")eta_time = get_MSC_related_time(tracking_number)else:print("===========================================")print("【PIL船司物流信息查询】")eta_time = get_PIL_related_time(tracking_number)return eta_timedef search_tracking_info_by_list(bl_list):"""遍历list查询物流信息:param bl_list: 提单列表:return: eta_time_List 预计到港时间列表"""eta_time_List = []for tracking_number in bl_list:eta_time = assign_shipper(tracking_number)eta_time_List.append(eta_time)return eta_time_Listdef get_latest_eta_time_and_insert_excel():"""1、读取excel里指定船公司的bill2、将通过bill查询返回的各大船司[预期到港时间]组成一个list3、在原excel里新增【new_ETA】列,并将最新查询到的【预期到港时间】写入- ZIM查询暂不稳定,所以先不写进去:return:"""sheet_name = "Sheet1"file_path = "./update_eta_time_client_list/update_eta_time_list.xlsx"df = pd.read_excel(file_path, sheet_name=sheet_name)bill_list = df["B/L"].to_list()print("bill_list", bill_list)eta_time_list = search_tracking_info_by_list(bill_list)print("eta_time_list:", eta_time_list)new_column_name = "new_ETA"  # 新增新ETA列new_loc = df.columns.get_loc('ETA') + 1df.insert(loc=new_loc, column=new_column_name, value=eta_time_list)  # 插入print("df:", df)df.to_excel(file_path, index=False)def get_local_time():"""获取本地日期 - 格式:2025/2/10:return:"""local_time = datetime.now()formatted_date = local_time.strftime('%Y/%#m/%#d')return formatted_datedef get_MSK_shipment_detail(bill_number):"""获取MSK物流详情:param bill_number::return: 返回符合excel表头的数据list"""response = get_MSK_tracking_info(bill_number)date = get_local_time()shipping = "MSK"index = 1bl_number = bill_numberorigin = response['origin']['city']destination = response['destination']['city']eta = get_MSK_related_time(bill_number)container_list = response['containers']telex_status = "N"data_list = []for container in container_list:print("container:", container)container_number = container['container_num']container_size = container['container_size']container_size_status = 1if container_size == '20':data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", "", container_size_status, origin, destination]elif container_size == '40':data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", container_size_status, "", origin, destination]data_list.append(data_total)index = index + 1print(f"MSK船司:共插入【{len(data_list)}】条数据")print("MSK船司新插入数据list:", data_list)return data_listdef get_COSCO_shipment_detail(bill_number):"""获取COSCO物流跟踪详情:param bill_number::return: list | 尺寸未填写"""response = get_COSCO_tracking_info(bill_number)date = get_local_time()content = response['data']['content']shipping = "COSCO"index = 1bl_number = bill_numberorigin = content['actualShipment'][0]['portOfLoading']destination = content['actualShipment'][0]['portOfDischarge']eta = get_COSCO_related_time(bill_number)telex_status = "N"data_list = []container_list = content['cargoTrackingContainer']for container_info in container_list:container_number = container_info['cntrNum']# print("container_info:", container_info)# print("ContainerNumber:", container_number)data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", "", "", origin, destination]data_list.append(data_total)index = index + 1print(f"COSCO船司:共插入【{len(data_list)}】条数据")print("COSCO船司新插入数据list:", data_list)return data_listdef get_MSC_shipment_detail(bill_number):"""获取MSC船司物流详细信息:param bill_number::return: list"""response = get_MSC_tracking_info(bill_number)bill_of_ladings = response['Data']['BillOfLadings'][0]print(bill_of_ladings)date = get_local_time()shipping = "MSC"index = 1bl_number = bill_numberorigin = bill_of_ladings['GeneralTrackingInfo']['ShippedFrom']destination = bill_of_ladings['GeneralTrackingInfo']['ShippedTo']eta = get_MSC_related_time(bill_number)container_list = bill_of_ladings['ContainersInfo']telex_status = "N"data_list = []for container_info in container_list:container_number = container_info['ContainerNumber']container_size = container_info['ContainerType']container_size_status = 1print("container_info:", container_info)print("ContainerNumber:", container_number)if container_size == "20' HIGH CUBE":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", "", container_size_status, origin, destination]elif container_size == "40' HIGH CUBE":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", container_size_status, "", origin, destination]data_list.append(data_total)index = index + 1print(f"MSC船司:共插入【{len(data_list)}】条数据")print("MSC船司新插入数据list:", data_list)return data_listdef get_ONE_shipment_detail(bill_number):"""获取ONE船司物流详情:param bill_number::return:"""response = get_ONE_tracking_info_by_bill_number(bill_number)bill_of_ladings = response['list']date = get_local_time()shipping = "ONE"index = 1bl_number = bill_number# origin = bill_of_ladings['GeneralTrackingInfo']['ShippedFrom']destination = bill_of_ladings[0]['placeNm']eta = get_ONE_related_time(bill_number)telex_status = "N"data_list = []for container_info in bill_of_ladings:container_number = container_info['cntrNo']container_size = container_info['cntrTpszNm']container_size_status = 1if container_size == "20'DRY HC.":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", "", container_size_status, "", destination]elif container_size == "40'DRY HC.":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", container_size_status, "", "", destination]data_list.append(data_total)index = index + 1print(f"ONE船司:共插入【{len(data_list)}】条数据")print("ONE船司新插入数据list:", data_list)return data_listdef get_ZIM_shipment_detail(bill_number):"""获取ZIM船司物流详情:param tracking_number::return: list"""response = get_ZIM_tracking_info(bill_number)blRouteLegs = response['message']['response']['blRouteLegs']container_list = response['message']['result']print("blRouteLegs:", blRouteLegs)date = get_local_time()shipping = "ZIM"index = 1bl_number = bill_numberorigin = blRouteLegs[0]['portNameFrom']destination = blRouteLegs[0]['portNameTo']eta = get_ZIM_related_time(bill_number)telex_status = "N"data_list = []for container_info in container_list:str = container_info['container']parts = str.split()  # 自动合并多个空格/制表符等空白字符part1, part2 = parts[0], parts[1]container_number = part1container_size = part2# print("container_number:", container_number)# print("container_size:", container_size)container_size_status = 1if container_size == "HC20":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", "", container_size_status, origin, destination]elif container_size == "HC40":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", container_size_status, "", origin, destination]data_list.append(data_total)index = index + 1print(f"ZIM船司:共插入【{len(data_list)}】条数据")print("ZIM船司新插入数据list:", data_list)return data_listdef get_PIL_shipment_detail(bill_number):"""获取PIL船司物流详情# todo: 解析方法需优化,适应各种情况;目前解析只默认拿取第一条柜子数据:param tracking_number::return: list"""response = get_PIL_tracking_info_by_bill_number(bill_number)print("PIL船信息:", response)data = response['data']date = get_local_time()shipping = "PIL"index = 1bl_number = bill_numbercontainer_list = data['table2']origin = container_list[0]['Place']str = data['table1'][0]['Next Location']parts = str.split()  # 自动合并多个空格/制表符等空白字符part1, part2 = parts[0], parts[1]destination = part1eta = get_PIL_related_time(bill_number)telex_status = "N"data_list = []for container_info in container_list:str = container_info['Container #']parts = str.split()  # 自动合并多个空格/制表符等空白字符part1, part2 = parts[0], parts[1]container_number = part1container_size = container_info['Size/Type']print("container_number:", container_number)print("container_size:", container_size)container_size_status = 1if container_size == "20GP":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", "", container_size_status, origin, destination]elif container_size == "40GP":data_total = [index, date, "", shipping, "", bl_number, "", container_number, date, eta,telex_status, "", "", "", container_size_status, "", origin, destination]data_list.append(data_total)index = index + 1print(f"PIL船司:共插入【{len(data_list)}】条数据")print("PIL船司新插入数据list:", data_list)return data_listdef insert_ship_detail_to_excel(tracking_number):"""将提单物流详情自动插入到excel中:param data_total: 数据list:param headers: 表头 - 这里我按需求写死就行:return:"""if type(tracking_number) != "str":tracking_number = str(tracking_number)if "COSU" in tracking_number or tracking_number[0] == '6' or tracking_number[0] == '9':print("===========================================")data_total = get_COSCO_shipment_detail(tracking_number)elif tracking_number[0] == '2':print("===========================================")data_total = get_MSK_shipment_detail(tracking_number)elif "GOSU" in tracking_number:print("===========================================")data_total = get_ZIM_shipment_detail(tracking_number)elif "ONEY" in tracking_number:print("===========================================")data_total = get_ONE_shipment_detail(tracking_number)elif "MEDU" in tracking_number or tracking_number[0] == '1':print("===========================================")data_total = get_MSC_shipment_detail(tracking_number)else:print("===========================================")data_total = get_PIL_shipment_detail(tracking_number)headers = ["Index", "Date", "Client", "Shipping","Goods", "B/L", "提单确认", "Container No.", "COPY件","ETA", "电放", "电放日期", "B/L2", "正本接收时间","40Q", "20Q", "Discharge", "Destination"]file_path = "./update_eta_time_client_list/auto_insert_new_bill_info.xlsx"if not Path(file_path).exists():pd.DataFrame(columns=headers)  # 不存在文件, 创建表头else:df = pd.read_excel(file_path)  # 读取现有数据new_df = pd.DataFrame(data_total, columns=headers)combined_df = pd.concat([df, new_df], ignore_index=True)  # 合并新旧数据combined_df.to_excel(file_path, index=False)  # 不保留索引列print(f"数据已追加至 {file_path}")def insert_ship_detail_list_to_excel(bl_list):"""批量插入物流信息到excel:param bl_list::return:"""for bill_number in bl_list:insert_ship_detail_to_excel(bill_number)# assign_shipper("GOSUNGB20516257") # 单个查询eta时间 - 自行判断哪个船司
# assign_shipper("COSU6404907671")
# assign_shipper("COSU9500786880")# get_latest_eta_time_and_insert_excel()  # 获取最新eta时间并写入excelbl_list = ["COSU6405220122","COSU6405220123","COSU6405220124"
]
insert_ship_detail_list_to_excel(bl_list)  # 批量插入数excel数据
# insert_ship_detail_to_excel("COSU6405220124")  # 自动将船司查询到的信息按规定表头写入excel表格
# insert_ship_detail_to_excel("COSU6405220124")  # 自动将船司查询到的信息按规定表头写入excel表格# bl_list = [
#     "MEDUKT219129",
#     "MEDUKT219137",
#     "MEDUKT297182"
#
# ]
# search_tracking_info_by_list(bl_list)  # 批量查询eta时间,传list# OOCL / CMA /HPL 加密,暂时无法破解;

相关文章:

Python(十九)实现各大跨境船公司物流查询数据处理优化

一、前言 之前已经实现了常用 跨境物流船司 基础信息查询功能,如下所示 实现各大跨境船公司[COSCO/ZIM/MSK/MSC/ONE/PIL]的物流信息查询:https://blog.csdn.net/Makasa/article/details/145484999?spm1001.2014.3001.5501 然后本章在其基础上做了一些…...

android 安装第三方apk自动赋予运行时权限

摘要:行业机使用场景点击运行时权限很麻烦,而随着android的演进,对于权限的管控越发严格。故本文通过对系统的修改实现第三方app在运行时直接获取全部权限。 通过属性ro.perms.force_grant控制功能开关。 Index: frameworks/base/services/…...

java8、9新特性

JAVA8 Lambda 表达式 (parameters) -> expression 或 (parameters) ->{ statements; } 提供了一种更为简洁的语法,尤其适用于函数式接口。相比于传统的匿名内部类,Lambda 表达式使得代码更为紧凑,减少了样板代码的编写。 它允许将函…...

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<9>

大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 这一节是对之前内容的修整 目录 一、传值调用和传址调用二、数组名的理解三、指针访问数组四、结尾 一…...

Java网络编程入门

网络编程是指通过计算机网络进行数据传输和通信的过程。在Java中,网络编程提供了一套强大的API,使得开发者能够轻松地创建网络应用程序。本文将介绍Java网络编程的基本概念和一些常用的类。 1.网络编程的基本概念 在网络编程中,我们通常需要…...

2.4 构建模块化应用

第4章:构建模块化应用 模块化应用是 JDK 9 的核心特性之一,通过模块化系统(Project Jigsaw)实现代码的强封装和显式依赖管理。本章详细讲解如何从零构建一个模块化应用,包括模块定义、编译、打包、运行及调试。 4.1 模…...

14.1 Auto-GPT 项目定位与价值解读:揭开自主智能体的神秘面纱

Auto-GPT 项目定位与价值解读:揭开自主智能体的神秘面纱 关键词:Auto-GPT 核心机制、自主任务分解、LangChain 智能体、持续自我优化、AGI 实践路径 一、为什么 Auto-GPT 能引爆技术圈? 1.1 从工具到员工的范式转移 维度传统AI系统Auto-GPT 智能体输入方式精确指令(“翻译…...

【Elasticsearch】分析器的构成

在Elasticsearch中,分析器(Analyzer)是一个处理文本数据的管道,它将输入的文本转换为一系列词元(tokens),并可以对这些词元进行进一步的处理和规范化。分析器由以下三个主要组件构成&#xff1a…...

2025 年前端开发现状分析:卷疯了还是卷麻了?

一、前端现状:框架狂飙,开发者崩溃 如果你是个前端开发者,那么你大概率经历过这些场景: 早上打开 CSDN(或者掘金,随便),发现又有新框架发布了,名字可能是 VueXNext.js 之…...

单例模式详解(Java)

单例模式详解(Java) 一、引言 1.1 概述单例模式的基本概念和重要性 单例模式是一种常用的软件设计模式,它确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点来访问这个唯一实例。这种模式在资源管理、配置设置和日志记录等方面非常有用,因为它们通常只需要…...

后端面试题

以下是一些常见的后端面试题: 一、通用基础 请简述HTTP协议的工作原理。 答案: HTTP是基于请求 - 响应模型的协议。客户端(通常是浏览器)向服务器发送一个HTTP请求,请求包含请求行(包含请求方法,如GET、POST等、请求的URL和HTTP版本)、请求头(包含诸如浏览器类型、接…...

深入理解Linux网络随笔(一):内核是如何接收网络包的(上篇)

深入理解Linux网络随笔(一):内核是如何接收网络包的(上篇) 1、TCP/IP模型概述 从Linux视角看,TCP/IP网络分层模型包括用户空间和内核空间。用户空间(应用层)负责HTTP、FTP等协议的…...

SQL-leetcode—1393. 股票的资本损益

1393. 股票的资本损益 Stocks 表: ---------------------- | Column Name | Type | ---------------------- | stock_name | varchar | | operation | enum | | operation_day | int | | price | int | ---------------------- (stock_name, operation_day) 是这张…...

热更图片方案

项目平常需要对线上一些图片资源修正,所以需要热更图片功能。 远端入口新增字段配json文件 {"1.1.22030303":{"sprite":{"assets/ui/common/images/acient_gold.png" : "https://aaaa.png","assets/ui/common/image…...

Flutter PIP 插件 ---- iOS Video Call

以下是一篇关于在 iOS 中实现画中画(PiP)功能的技术博客: iOS 画中画(PiP)功能实现指南 简介 画中画(Picture in Picture, PiP)是一项允许用户在使用其他应用时继续观看视频内容的功能。本文将详细介绍如何在 iOS 应用中实现 PiP 功能。 系统要求 iOS 15.0 及以上版本AVKi…...

本地部署DeepSeek开源大模型:从零开始的详细教程

友情提示:本文内容全部由银河易创(https://ai.eaigx.com)AI创作平台deepseek-reasoner模型生成,仅供参考。请根据具体情况和需求进行适当的调整和验证。 近年来,随着人工智能技术的飞速发展,大模型在各个领…...

java项目之基于SSM会议管理系统的设计与实现源码(ssm+mysql)

项目简介 基于SSM会议管理系统的设计与实现实现了以下功能: 基于SSM会议管理系统的设计与实现的主要使用者分为:管理员登录后修改个人的密码。用户管理中,对公司内的用户进行管理,包括会议管理员和员工,管理部门信息…...

PortSwigger——WebSockets vulnerabilities

文章目录 一、WebSockets二、Lab: Manipulating WebSocket messages to exploit vulnerabilities三、Lab: Manipulating the WebSocket handshake to exploit vulnerabilities四、Using cross-site WebSockets to exploit vulnerabilities4.1 跨站WebSocket劫持(cro…...

STM32系统架构介绍

STM32系统架构 1. CM3/4系统架构2. CM3/4系统架构-----存储器组织结构2.1 寄存器地址映射(特殊的存储器)2.2 寄存器地址计算2.3 寄存器的封装 3. CM3/4系统架构-----时钟系统 STM32 和 ARM 以及 ARM7是什么关系? ARM 是一个做芯片标准的公司&#xff0c…...

智能GUI Agent是什么,有什么应用领域

智能GUI Agent是什么 研究背景与目的:GUI长期主导人机交互,LLM特别是多模态模型的出现,为GUI自动化带来变革,催生了基于LLM的GUI智能体。这些智能体可理解自然语言指令,处理复杂GUI元素并执行操作,改变了用户与软件交互方式。论文旨在梳理该领域发展脉络,剖析关键要素,…...

Python3操作MongoDB批量upsert

个人博客地址:Python3操作MongoDB批量upsert | 一张假钞的真实世界 代码如下: mongoClient MongoClient(mongodb://172.16.72.213:27017/) opsDb mongoClient.ops azScheduled opsDb.azScheduledFlowbulkOpers [] for flow in scheduledFlows.valu…...

3dgs 2025 学习笔记

CVPR 2024 3D方向总汇包含(3DGS、三维重建、深度补全、深度估计、全景定位、表面重建和特征匹配等)_cvpr2024-structure-awaresparse-viewx-ray3dreconstr-CSDN博客 https://github.com/apple/ml-hugs 3DGS COLMAP-Free 3D Gaussian Splatting ⭐code &…...

大模型笔记:pytorch实现MOE

0 导入库 import torch import torch.nn as nn import torch.nn.functional as F 1 专家模型 #一个简单的专家模型,可以是任何神经网络架构 class Expert(nn.Module):def __init__(self, input_size, output_size):super(Expert, self).__init__()self.fc nn.L…...

C#/.NET/.NET Core技术前沿周刊 | 第 25 期(2025年2.1-2.9)

前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。 欢迎投稿、推荐…...

package.json 文件配置

创建 Node.js 的配置文件 package.json npm init -y package.json 文件配置说明 配置说明示例name指定项目的名称,必须是小写字母,可以包含字母、数字、连字符(-)或下划线(_),不能有特殊字符…...

相机模数转换

模拟图像是什么? 模拟图像是指连续变化的图像,它通常来源于现实世界的物理场景,并通过光学系统(如相机镜头)投射到感光介质上。模拟图像是连续的,这意味着它在空间和颜色值上都有无穷的细节。例如&#xf…...

mysql大数据量分页查询

一、什么是‌MySQL大数据量分页查? MySQL大数据量分页查‌是指在使用MySQL数据库时,将大量数据分成多个较小的部分进行显示,以提高查询效率和用户体验。分页查询通常用于网页或应用程序中,以便用户能够逐步浏览结果集。 二、为什…...

组织结构改革:激活企业活力的 “源头活水”

难以适应市场变化、内部沟通与协作不畅、决策效率低下、运营成本增加、人才流失严重、员工士气下降、战略目标难以实现……企业如何根据市场环境变化和自身发展需求,灵活调整组织框架,赋能企业的持续健康发展? 某国有投资建设集团旗下的二级…...

金融风控项目-1

文章目录 一. 案例背景介绍二. 代码实现1. 加载数据2. 数据处理3. 查询 三. 业务解读 一. 案例背景介绍 通过对业务数据分析了解信贷业务状况 数据集说明 从开源数据改造而来,基本反映真实业务数据销售,客服可以忽略账单周期,放款日期账单金…...

Java常用设计模式面试题总结(内容详细,简单易懂)

设计模式的分类 创建型模式:通过隐藏对象创建的细节,避免直接使用 new 关键字实例化对象,从而使程序在判断和创建对象时更具灵活性。常见的模式包括: 工厂模式抽象工厂模式单例模式建造者模式原型模式 结构型模式:通…...

【Elasticsearch】文本分析Text analysis概述

文本分析概述 文本分析使 Elasticsearch 能够执行全文搜索,搜索结果会返回所有相关的结果,而不仅仅是完全匹配的结果。 如果你搜索“Quick fox jumps”,你可能希望找到包含“A quick brown fox jumps over the lazy dog”的文档&#xff0c…...

ATF系统安全从入门到精通

CSDN学院课程连接:https://edu.csdn.net/course/detail/39573...

C# 上位机--变量

C# 上位机--变量 在 C# 上位机开发领域,变量是构建程序逻辑的基础元素之一。它就像是一个容器,用于存储各种类型的数据,从简单的数值到复杂的对象。正确理解和使用变量,对于开发出高效、稳定且易于维护的上位机程序至关重要。本文…...

π 的奥秘:如何用有理数逼近无理数?

本文将围绕有理数、无理数、连续统以及它们之间的深刻联系展开讨论,并结合具体的数学理论如康托尔区间套定理、戴德金分割、柯西施瓦茨不等式等,进行简要探讨 由于本文并未深入探讨,可能存在部分不严谨的地方,也欢迎各位进行纠正…...

LeetCode --- 436周赛

题目列表 3446. 按对角线进行矩阵排序 3447. 将元素分配给有约束条件的组 3448. 统计可以被最后一个数位整除的子字符串数目 3449. 最大化游戏分数的最小值 一、按对角线进行矩阵排序 直接模拟,遍历每一个斜对角线,获取斜对角线上的数字,排…...

绘制中国平安股价的交互式 K 线图

在本文中,探索如何使用 Python 的强大库进行股市数据分析与可视化。我们将以中国平安(股票代码:sh601318)为例,展示如何获取其股票数据,并绘制一张交互式 K 线图。 K 线图是股市分析中不可或缺的工具,它能够直观地显示股票的波动情况,包括开盘价、收盘价、最高价和最低…...

【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第二节】

ISO 14229-1:2023 UDS诊断服务测试用例全解析(ECU复位0x11服务) 作者:车端域控测试工程师 更新日期:2025-02-12 关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023 二、ECU复位服务(0x11服务&…...

Unity URP的2D光照简介

官网工程,包括2d光照,动画,动效介绍: https://unity.com/cn/blog/games/happy-harvest-demo-latest-2d-techniques https://docs.unity3d.com/6000.0/Documentation/Manual/urp/Lights-2D-intro.html 人物脸部光照细节和脚上的阴影…...

自学人工智能大模型,满足7B模型的训练和微调以及推理,预算3万,如何选购电脑

如果你的预算是 3万元人民币,希望训练和微调 7B 参数规模的人工智能大模型(如 LLaMA、Mistral 等),你需要一台高性能的深度学习工作站。在这个预算范围内,以下是推荐的配置: 1. 关键硬件配置 (1) GPU (显卡…...

shell脚本自动安装MySQL8

环境:centos7版本:8.0.28安装包:mysql-8.0.28-linux-glibc2.12-x86_64.tar.xz 二进制包要求:安装包和shell脚本在同一目录下执行方式:sudo ./install_mysql8.sh #!/bin/bash# 定义MySQL安装目录和压缩包名称MYSQL_DIR…...

使用亚马逊针对 PyTorch 和 MinIO 的 S3 连接器进行模型检查点处理

2023 年 11 月,Amazon 宣布推出适用于 PyTorch 的 S3 连接器。适用于 PyTorch 的 Amazon S3 连接器提供了专为 S3 对象存储构建的 PyTorch 数据集基元(数据集和数据加载器)的实现。它支持用于随机数据访问模式的地图样式数据集和用于流式处理…...

DeepAR:一种用于时间序列预测的深度学习模型

介绍 DeepAR是一种基于递归神经网络(RNN)的时间序列预测模型,由亚马逊在2017年提出。它特别适用于处理多变量时间序列数据,并能够生成概率预测。DeepAR通过联合训练多个相关时间序列来提高预测性能,从而在实际应用中表…...

【无标题】《On Java中文版基础卷+进阶卷》书评

Java语言作为最热门的编程语言之一,关于Java语言的书更是数不胜数,而我选择这本《On Java中文版基础卷进阶卷》作为我学习Java语言的工具书。这本书的作者是《Java编程思想》的Bruce Eckel,《Java编程思想》在之前可谓是鼎鼎有名,…...

【鸿蒙开发】第二十九章 Stage模型-应用上下文Context、进程、线程

目录 1 Stage模型基本概念 1.1 开发流程 3 应用上下文Context的典型使用场景 3.1 获取应用文件路径 3.2 获取和修改加密分区 3.3 获取本应用中其他Module的Context 3.4 订阅进程内UIAbility生命周期变化 4 进程 4.1 概述 5 线程 5.1 线程类型 5.2 使用EventHub进行线…...

AI-Engine-Direct-Helper 快速上手及环境配置

AI-Engine-Direct-Helper 是一个强大的工具,旨在简化和加速在 Qualcomm 平台上开发 AI 应用的过程。通过提供统一的 API、跨平台支持和高效的执行性能,它为开发者提供了一个灵活且高效的开发环境。如果您正在使用 Qualcomm 平台进行 AI 开发,…...

网络安全产品架构图 网络安全相关产品

一、信息安全产品分类 背景 美国将网络和信息安全产品分了9类:鉴别、访问控制、入侵检测、防火墙、公钥基础设施、恶意程序代码防护、漏洞扫描、取证、介质清理或擦除。中国公安部将网络和信息安全产品分了7类:操作系统安全、数据库安全、网络安全、病毒…...

日常知识点之面试后反思裸写string类

1:实现一个字符串类。 简单汇总 最简单的方案,使用一个字符串指针,以及实际字符串长度即可。 参考stl的实现,为了提升string的性能,实际上单纯的字符串指针和实际长度是不够了,如上,有优化方案…...

Linux(socket网络编程)TCP连接

Linux(socket网络编程)TCP连接 基础文件目录函数系统进程控制函数fork()exec系列函数void abort(void)void assert(int expression)void exit(int status)void _exit(int status)int atexit(void (*func)(void))int on_exit(void (*function)(int,void*)…...

深入 JVM 虚拟机:字符串常量池演变与 intern() 方法工作原理解析

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template 🌺 仓库主页: GitCode︱ Gitee ︱ Github 💖 欢迎点赞 👍 收藏 ⭐评论 📝 如有错误敬请纠正! 前言 在 Java 开发中,字符串常量池(String Constant…...

从零开始学习人工智能

从零开始学习人工智能可以按照以下步骤进行: 一、了解人工智能的基本概念 学习内容:了解人工智能的定义、发展历程、主要研究方向(如机器学习、深度学习、自然语言处理、计算机视觉等)、常见应用(如语音识别、图像识别…...