You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

144 lines
5.1 KiB

#!/usr/bin/env python3
"""
智能快递查询工具 - 多方法查询
"""
import requests
import json
import re
import sys
from datetime import datetime
def query_method1_jd_api(tracking_number):
"""方法1:尝试京东物流公开查询接口"""
try:
url = f"https://api.jd.com/logistics/track/query?deliveryId={tracking_number}"
headers = {
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15',
}
response = requests.get(url, headers=headers, timeout=5)
return f"方法1状态: {response.status_code}"
except Exception as e:
return f"方法1失败: {str(e)}"
def query_method2_kuaidi100_scrape(tracking_number):
"""方法2:尝试快递100网页查询"""
try:
session = requests.Session()
# 先访问首页获取cookie
session.get('https://www.kuaidi100.com', headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
# 自动识别快递
auto_url = f"https://www.kuaidi100.com/autonumber/auto?num={tracking_number}"
auto_response = session.get(auto_url, timeout=5)
if auto_response.status_code == 200 and auto_response.text:
try:
auto_data = auto_response.json()
if auto_data:
company = auto_data[0].get('name', '未知')
com_code = auto_data[0].get('comCode', '')
# 查询详细信息
query_url = f"https://www.kuaidi100.com/query?type={com_code}&postid={tracking_number}"
query_response = session.get(query_url, timeout=5)
if query_response.status_code == 200:
result = query_response.json()
return parse_kuaidi100(result, company)
except:
pass
return "方法2:未能获取有效数据"
except Exception as e:
return f"方法2失败: {str(e)}"
def query_method3_multiple_sources(tracking_number):
"""方法3:尝试多个公开数据源"""
results = []
# 尝试不同的公开查询API
test_urls = [
f"https://api.kuaidi100.com/api?id=1&com=jd&nu={tracking_number}",
f"https://www.kuaidi.com/index-ajaxselectcourierinfo-{tracking_number}-jd.html",
]
for url in test_urls:
try:
response = requests.get(url, headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}, timeout=5)
if response.status_code == 200 and len(response.content) > 100:
results.append(f"找到可能数据源: {url[:60]}...")
except:
continue
return results if results else "方法3:未找到可用数据源"
def parse_kuaidi100(data, company_name):
"""解析快递100数据"""
output = []
output.append(f"📦 快递公司: {company_name}")
if data.get('status') == '200':
state_map = {
'0': '在途', '1': '揽收', '2': '疑难',
'3': '签收', '4': '退签', '5': '派件', '6': '退回'
}
state = data.get('state', '')
output.append(f"🚚 物流状态: {state_map.get(state, '未知')}")
output.append("")
output.append("📋 物流轨迹:")
traces = data.get('data', [])
if traces:
for i, trace in enumerate(traces[:5]): # 只显示最近5条
time = trace.get('time', '')
context = trace.get('context', '')
output.append(f" {i+1}. {time} - {context}")
if len(traces) > 5:
output.append(f" ... 还有 {len(traces)-5} 条记录")
else:
output.append(" 暂无物流轨迹")
else:
output.append(f"❌ 查询失败: {data.get('message', '未知错误')}")
return "\n".join(output)
def main():
tracking_number = sys.argv[1] if len(sys.argv) > 1 else "JDX049504693863"
print("=" * 60)
print(f"📦 正在查询快递单号: {tracking_number}")
print("=" * 60)
print(f"查询时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("")
# 根据单号前缀判断
if tracking_number.startswith('JDX') or tracking_number.startswith('JD'):
print("📌 识别为: 京东物流 (JD Express)")
print("")
# 尝试方法2(快递100)
print("🔍 正在使用快递100查询...")
result2 = query_method2_kuaidi100_scrape(tracking_number)
print(result2)
print("")
# 提供备用查询方法
print("💡 备用查询方案:")
print(" 1. 京东APP - 最准确")
print(" 2. https://www.jd.com - 官网查询")
print(" 3. 京东客服: 950616")
else:
print("📌 未知快递公司,请使用第三方平台查询")
print(" 快递100: https://www.kuaidi100.com")
print(" 菜鸟裹裹: https://www.cainiao.com")
print("")
print("=" * 60)
if __name__ == "__main__":
main()