一、时间戳是什么
做爬虫的时候,时间戳是最常见的参数之一。很多接口要求传入 timestamp 参数,而且格式各不相同:有的要秒级,有的要毫秒级,有的要微秒级。搞不清楚这些区别,请求就会失败。
时间戳(Timestamp)是从某个固定时间点开始计算的秒数或毫秒数。最常用的是 Unix 时间戳,从 1970 年 1 月 1 日 00:00:00 UTC 开始计算。
时间戳的精度
- 秒级:10 位数字,如 1705315200
- 毫秒级:13 位数字,如 1705315200000
- 微秒级:16 位数字,如 1705315200000000
二、基础操作
2.1 获取当前时间戳
import time
from datetime import datetime
# 秒级时间戳
seconds = int(time.time())
print(f"秒级: {seconds}") # 1705315200
# 毫秒级时间戳
milliseconds = int(time.time() * 1000)
print(f"毫秒级: {milliseconds}") # 1705315200000
# 微秒级时间戳
microseconds = int(time.time() * 1000000)
print(f"微秒级: {microseconds}") # 1705315200000000
2.2 时间戳转日期
# 秒级转日期
timestamp = 1705315200
dt = datetime.fromtimestamp(timestamp)
print(dt) # 2024-01-15 16:00:00
# 毫秒级转日期(先除以 1000)
timestamp_ms = 1705315200000
dt = datetime.fromtimestamp(timestamp_ms / 1000)
print(dt) # 2024-01-15 16:00:00
2.3 日期转时间戳
# 当前日期转时间戳
dt = datetime.now()
timestamp = int(dt.timestamp())
print(f"秒级: {timestamp}")
# 指定日期转时间戳
dt = datetime(2024, 1, 15, 16, 0, 0)
timestamp = int(dt.timestamp())
print(f"秒级: {timestamp}") # 1705315200
三、格式转换
3.1 字符串转日期
from datetime import datetime
# 解析各种格式
dt1 = datetime.strptime('2024-01-15', '%Y-%m-%d')
dt2 = datetime.strptime('2024-01-15 16:30:00', '%Y-%m-%d %H:%M:%S')
dt3 = datetime.strptime('15/01/2024', '%d/%m/%Y')
dt4 = datetime.strptime('Jan 15, 2024', '%b %d, %Y')
print(dt1) # 2024-01-15 00:00:00
print(dt2) # 2024-01-15 16:30:00
3.2 日期转字符串
from datetime import datetime
dt = datetime.now()
# 各种格式
print(dt.strftime('%Y-%m-%d')) # 2024-01-15
print(dt.strftime('%Y-%m-%d %H:%M:%S')) # 2024-01-15 16:30:00
print(dt.strftime('%d/%m/%Y')) # 15/01/2024
print(dt.strftime('%Y年%m月%d日')) # 2024年01月15日
3.3 常用格式符
| 格式符 | 含义 | 示例 |
|---|---|---|
| %Y | 四位年份 | 2024 |
| %m | 月份(01-12) | 01 |
| %d | 日期(01-31) | 15 |
| %H | 小时(24小时制) | 16 |
| %M | 分钟(00-59) | 30 |
| %S | 秒(00-59) | 00 |
| %f | 微秒 | 000000 |
四、时区处理
4.1 带时区的时间
from datetime import datetime, timezone, timedelta
# UTC 时间
utc_now = datetime.now(timezone.utc)
print(f"UTC: {utc_now}")
# 东八区时间(北京时间)
beijing_tz = timezone(timedelta(hours=8))
beijing_now = datetime.now(beijing_tz)
print(f"北京: {beijing_now}")
# 转换时区
utc_time = datetime.now(timezone.utc)
beijing_time = utc_time.astimezone(beijing_tz)
print(f"UTC 转北京: {beijing_time}")
4.2 使用 pytz
import pytz
from datetime import datetime
# 获取时区
beijing = pytz.timezone('Asia/Shanghai')
new_york = pytz.timezone('America/New_York')
# 创建带时区的时间
dt = datetime(2024, 1, 15, 16, 0, 0)
dt_beijing = beijing.localize(dt)
print(f"北京: {dt_beijing}")
# 转换时区
dt_ny = dt_beijing.astimezone(new_york)
print(f"纽约: {dt_ny}")
五、爬虫中的时间处理
5.1 生成接口所需的时间戳
import time
def get_timestamp(unit='ms'):
"""获取时间戳"""
if unit == 's':
return int(time.time())
elif unit == 'ms':
return int(time.time() * 1000)
elif unit == 'us':
return int(time.time() * 1000000)
else:
raise ValueError("unit 必须是 's', 'ms' 或 'us'")
# 使用
ts_s = get_timestamp('s')
ts_ms = get_timestamp('ms')
print(f"秒级: {ts_s}")
print(f"毫秒级: {ts_ms}")
5.2 解析接口返回的时间
from datetime import datetime
def parse_api_time(time_value):
"""解析 API 返回的各种时间格式"""
# 如果是数字(时间戳)
if isinstance(time_value, (int, float)):
# 判断是秒级还是毫秒级
if time_value > 1e12: # 毫秒级
return datetime.fromtimestamp(time_value / 1000)
else: # 秒级
return datetime.fromtimestamp(time_value)
# 如果是字符串
elif isinstance(time_value, str):
formats = [
'%Y-%m-%d %H:%M:%S',
'%Y-%m-%d',
'%d/%m/%Y %H:%M:%S',
'%Y年%m月%d日',
]
for fmt in formats:
try:
return datetime.strptime(time_value, fmt)
except ValueError:
continue
raise ValueError(f"无法解析时间格式: {time_value}")
# 使用
print(parse_api_time(1705315200))
print(parse_api_time(1705315200000))
print(parse_api_time('2024-01-15 16:00:00'))
六、常见问题
6.1 时间戳长度判断
def detect_timestamp_unit(timestamp):
"""判断时间戳的精度"""
length = len(str(int(timestamp)))
if length == 10:
return '秒级'
elif length == 13:
return '毫秒级'
elif length == 16:
return '微秒级'
else:
return '未知'
# 使用
print(detect_timestamp_unit(1705315200)) # 秒级
print(detect_timestamp_unit(1705315200000)) # 毫秒级
6.2 时间加减
from datetime import datetime, timedelta
dt = datetime.now()
# 加一天
tomorrow = dt + timedelta(days=1)
print(f"明天: {tomorrow}")
# 减一小时
last_hour = dt - timedelta(hours=1)
print(f"一小时前: {last_hour}")
# 加 30 分钟
after_30min = dt + timedelta(minutes=30)
print(f"30分钟后: {after_30min}")
七、总结
时间处理是爬虫开发中的基础技能。记住这几个核心要点:
| 操作 | 方法 | 注意事项 |
|---|---|---|
| 获取当前时间戳 | time.time() |
返回浮点数,秒级 |
| 时间戳转日期 | datetime.fromtimestamp() |
毫秒级需要先除以 1000 |
| 日期转字符串 | dt.strftime() |
注意格式符大小写 |
| 字符串转日期 | datetime.strptime() |
格式必须匹配 |
| 时区转换 | astimezone() |
推荐用 pytz |
时间处理看起来简单,但细节很多。建议把常用的函数封装成工具类,项目中直接调用,避免重复造轮子。