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.
127 lines
3.7 KiB
127 lines
3.7 KiB
#!/usr/bin/env python3
|
|
"""
|
|
快递查询工具
|
|
支持京东快递查询
|
|
"""
|
|
|
|
import requests
|
|
import re
|
|
import json
|
|
import sys
|
|
from datetime import datetime
|
|
|
|
def query_jd_express(tracking_number):
|
|
"""
|
|
查询京东快递物流信息
|
|
"""
|
|
try:
|
|
# 京东物流查询API
|
|
url = f"https://www.jd.com/logisticsAction/getLogisticsInfo?deliveryId={tracking_number}"
|
|
|
|
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',
|
|
'Referer': 'https://www.jd.com/',
|
|
'Accept': 'application/json, text/plain, */*',
|
|
}
|
|
|
|
response = requests.get(url, headers=headers, timeout=10)
|
|
|
|
if response.status_code == 200:
|
|
try:
|
|
data = response.json()
|
|
return parse_jd_response(data)
|
|
except json.JSONDecodeError:
|
|
# 尝试解析文本响应
|
|
return parse_jd_html(response.text)
|
|
else:
|
|
return f"查询失败,HTTP状态码: {response.status_code}"
|
|
|
|
except Exception as e:
|
|
return f"查询过程中出现错误: {str(e)}"
|
|
|
|
def parse_jd_response(data):
|
|
"""
|
|
解析京东API响应
|
|
"""
|
|
if not data or 'data' not in data:
|
|
return "未找到物流信息"
|
|
|
|
result = []
|
|
|
|
# 提取基本信息
|
|
logistics_info = data.get('data', {})
|
|
|
|
# 快递公司信息
|
|
company = logistics_info.get('companyName', '京东物流')
|
|
status = logistics_info.get('statusDesc', '未知状态')
|
|
|
|
result.append(f"快递公司: {company}")
|
|
result.append(f"物流状态: {status}")
|
|
result.append("")
|
|
|
|
# 物流轨迹
|
|
traces = logistics_info.get('traces', [])
|
|
if traces:
|
|
result.append("物流轨迹:")
|
|
for trace in traces:
|
|
time_str = trace.get('acceptTime', '')
|
|
desc = trace.get('acceptStation', '')
|
|
if time_str and desc:
|
|
result.append(f" {time_str} - {desc}")
|
|
else:
|
|
result.append("暂无物流轨迹信息")
|
|
|
|
return "\n".join(result)
|
|
|
|
def parse_jd_html(html_content):
|
|
"""
|
|
解析京东HTML页面
|
|
"""
|
|
# 简单的HTML解析
|
|
patterns = [
|
|
r'"statusDesc":"([^"]+)"',
|
|
r'"acceptTime":"([^"]+)"',
|
|
r'"acceptStation":"([^"]+)"',
|
|
r'<div[^>]*class="logistics-detail-item"[^>]*>([^<]+)<\/div>',
|
|
r'<div[^>]*class="logistics-time"[^>]*>([^<]+)<\/div>',
|
|
]
|
|
|
|
result = []
|
|
result.append("快递公司: 京东物流")
|
|
|
|
# 尝试提取状态信息
|
|
status_match = re.search(r'"statusDesc":"([^"]+)"', html_content)
|
|
if status_match:
|
|
result.append(f"物流状态: {status_match.group(1)}")
|
|
|
|
# 提取物流轨迹
|
|
traces = []
|
|
time_matches = re.findall(r'"acceptTime":"([^"]+)"', html_content)
|
|
station_matches = re.findall(r'"acceptStation":"([^"]+)"', html_content)
|
|
|
|
if time_matches and station_matches:
|
|
result.append("")
|
|
result.append("物流轨迹:")
|
|
for i in range(min(len(time_matches), len(station_matches))):
|
|
result.append(f" {time_matches[i]} - {station_matches[i]}")
|
|
elif "暂无物流信息" in html_content:
|
|
result.append("暂无物流信息")
|
|
else:
|
|
result.append("物流信息解析失败")
|
|
|
|
return "\n".join(result)
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("使用方法: python express_query.py <快递单号>")
|
|
sys.exit(1)
|
|
|
|
tracking_number = sys.argv[1]
|
|
print(f"正在查询快递单号: {tracking_number}")
|
|
print("=" * 50)
|
|
|
|
result = query_jd_express(tracking_number)
|
|
print(result)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|