本文目录导读:

使用快递鸟API(推荐)
import requests
import json
class LogisticsQuery:
def __init__(self, app_id, app_key):
self.app_id = app_id
self.app_key = app_key
self.url = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx"
def query(self, exp_code, exp_no):
"""查询物流信息
exp_code: 快递公司编码 (如 SFEXPRESS, YTO)
exp_no: 运单号
"""
request_data = {
"OrderCode": "",
"ShipperCode": exp_code,
"LogisticCode": exp_no
}
# 生成签名
data_str = json.dumps(request_data, separators=(',',':'))
sign = self._build_sign(data_str)
params = {
"RequestType": "1002",
"EBusinessID": self.app_id,
"RequestData": data_str,
"DataSign": sign,
"DataType": "2"
}
response = requests.post(self.url, data=params)
return response.json()
def _build_sign(self, data_str):
import hashlib
sign_str = data_str + self.app_key
sign = hashlib.md5(sign_str.encode()).hexdigest()
return sign
# 使用示例
if __name__ == "__main__":
# 需要在快递鸟官网注册获取
app_id = "你的APP_ID"
app_key = "你的APP_KEY"
query = LogisticsQuery(app_id, app_key)
result = query.query("SFEXPRESS", "SF1234567890")
print(json.dumps(result, indent=2, ensure_ascii=False))
使用快递100API
import requests
import hashlib
import json
class Kuaidi100Query:
def __init__(self, key, customer):
self.key = key
self.customer = customer
self.url = "https://poll.kuaidi100.com/poll/query.do"
def query(self, com, num):
"""查询物流信息"""
param = {
"com": com, # 快递公司编码
"num": num # 运单号
}
param_str = json.dumps(param)
sign = hashlib.md5((param_str + self.key + self.customer).encode()).hexdigest().upper()
data = {
"customer": self.customer,
"param": param_str,
"sign": sign
}
response = requests.post(self.url, data=data)
return response.json()
# 使用示例
query = Kuaidi100Query("你的KEY", "你的CUSTOMER")
result = query.query("yuantong", "YT1234567890")
使用爬虫方式(仅用于学习)
import requests
from bs4 import BeautifulSoup
import re
class SimpleLogisticsQuery:
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def query_baidu(self, exp_no):
"""使用百度查询物流信息"""
url = f"https://www.baidu.com/s?wd={exp_no}"
response = requests.get(url, headers=self.headers)
# 解析HTML提取物流信息
soup = BeautifulSoup(response.text, 'html.parser')
# 这里需要根据实际页面结构解析
def query_17track(self, exp_no):
"""使用17track查询"""
url = f"https://www.17track.net/en/track?nums={exp_no}"
response = requests.get(url, headers=self.headers)
# 解析结果
# 注意:爬虫方式不稳定,且可能违反网站服务条款
批量查询脚本(带缓存)
import json
import time
import sqlite3
from datetime import datetime
class BatchLogisticsQuery:
def __init__(self, api_instance):
self.api = api_instance
self.cache = {}
self.init_db()
def init_db(self):
"""初始化SQLite缓存数据库"""
self.conn = sqlite3.connect('logistics_cache.db')
self.cursor = self.conn.cursor()
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS cache (
exp_no TEXT PRIMARY KEY,
result TEXT,
update_time TIMESTAMP
)
''')
self.conn.commit()
def get_from_cache(self, exp_no):
"""从缓存获取数据"""
self.cursor.execute(
"SELECT result, update_time FROM cache WHERE exp_no=?",
(exp_no,)
)
result = self.cursor.fetchone()
if result:
# 180分钟内的缓存有效
update_time = datetime.strptime(result[1], '%Y-%m-%d %H:%M:%S')
if (datetime.now() - update_time).seconds < 10800:
return json.loads(result[0])
return None
def save_to_cache(self, exp_no, result):
"""保存到缓存"""
self.cursor.execute(
"REPLACE INTO cache (exp_no, result, update_time) VALUES (?, ?, ?)",
(exp_no, json.dumps(result), datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
)
self.conn.commit()
def batch_query(self, exp_list, delay=1):
"""批量查询(带延迟避免被封)"""
results = {}
for exp_no in exp_list:
# 先查缓存
cached = self.get_from_cache(exp_no)
if cached:
results[exp_no] = cached
print(f"{exp_no}: 使用缓存数据")
else:
# 实时查询
try:
result = self.api.query(exp_no)
results[exp_no] = result
self.save_to_cache(exp_no, result)
print(f"{exp_no}: 查询成功")
time.sleep(delay) # 避免请求过快
except Exception as e:
print(f"{exp_no}: 查询失败 - {str(e)}")
return results
命令行工具版本
import argparse
import sys
def main():
parser = argparse.ArgumentParser(description='物流信息查询工具')
parser.add_argument('exp_no', help='快递单号')
parser.add_argument('--company', '-c', help='快递公司编码(可选)')
parser.add_argument('--output', '-o', help='输出文件路径')
parser.add_argument('--format', '-f', choices=['json', 'text'], default='text', help='输出格式')
args = parser.parse_args()
# 查询逻辑
result = query_logistics(args.exp_no, args.company)
# 输出
if args.format == 'json':
output = json.dumps(result, indent=2, ensure_ascii=False)
else:
output = format_text(result)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(output)
else:
print(output)
if __name__ == "__main__":
main()
注意事项
- API使用:推荐使用正规API服务,需要注册获取密钥
- 爬虫限制:爬虫方式不稳定且可能违法,仅用于学习
- 频率限制:批量查询时要控制请求频率
- 数据缓存:避免重复请求同一运单
- 错误处理:做好异常捕获和重试机制
需要我详细讲解某个具体实现吗?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播