datetime
datetime是Python处理日期和时间的标准库
获取当前日期和时间
# 获取当前datetime
now = datetime.now()
print(now)
2020-07-31 08:52:15.794540
Process finished with exit code 0
datetime.now()返回当前日期和时间,其类型是datetime
获取指定日期和时间
要指定某个日期和时间,我们直接用参数构造一个datetime即可
# 获取指定日期和时间
dt = datetime(2018, 6, 21, 12, 20)
print(dt)
2018-06-21 12:20:00
Process finished with exit code 0
datetime转换为timestamp
在计算机中,时间实际上是用数字表示的。我们把1970年1月1日00:00:00 UTC+00:00 记为0
now = datetime.now()
print(now.timestamp())
1596157122.191671
Process finished with exit code 0
注意,Python的timestamp是一个浮点数,小数位表示毫秒数
某些编程语言(如Java和JavaScript)的timestamp使用整数表示毫秒数,这种情况下只需把timestamp除以1000就得到了Python的浮点表示方法
timestamp转换为datetime
t = now.timestamp()
print(datetime.fromtimestamp(t))
2020-07-31 09:02:27.456935
Process finished with exit code 0
上述转换是在timestamp和本地时间做转换,本地时间是指当前操作系统设定的时区
当然,timestamp也可以直接被转换到UTC标准时间
datetime.utcfromtimestamp(t)
str转换为datetime
str2time = datetime.strptime('2020-7-31 18:19:40', '%Y-%m-%d %H:%M:%S')
print(str2time)
2020-07-31 18:19:40
Process finished with exit code 0
datetime转换成str
now.strftime('%a, %b %d %H:%M')
Fri, Jul 31 09:08
Process finished with exit code 0
datetime的加减
对日期和时间进行加减相当于datetime往后或往前计算,需要导入timedelta这个类
# datetime加减
now = datetime.now()
print(now)
print(now + timedelta(hours=10))
print(now - timedelta(days=1))
2020-07-31 09:11:40.597967
2020-07-31 19:11:40.597967
2020-07-30 09:11:40.597967
Process finished with exit code 0
本地时间转换为UTC时间
本地时间是指系统设定时区的时间
一个datetime类型有一个时区属性tzinfo,但是默认是None,因此我们需要给datetime设置一个时区
tz_utc_8 = timezone(timedelta(hours=8)) # 创建时区UTC+8:00
now = datetime.now()
print(now)
dt = now.replace(tzinfo=tz_utc_8) # 设置时区
print(dt)
时区转换
我们可以通过utcnow()拿到当前的UTC时间,再转换为任意时区的时间
# 时区转换
utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
print(utc_dt)
bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8))) # 北京时间
print(bj_dt)
2020-07-31 01:19:19.739637+00:00
2020-07-31 09:19:19.739637+08:00
Process finished with exit code 0
collections
collections是Python内置的一个集合模块,提供了许多有用的集合类
namedtuple
namedtuple是一个函数,它可以用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素
# 定义一个点的二维坐标
Point = namedtuple('Point', ['x', 'y'])
p = Point(2, 3)
print(p.x, p.y)
2 3
Process finished with exit code 0
deque
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
# deque
q = deque([1, 2, 3])
q.append(4)
q.append(9)
q.appendleft(0)
q.appendleft(-1)
print(q)
q.pop()
q.popleft()
print(q)
deque([-1, 0, 1, 2, 3, 4, 9])
deque([0, 1, 2, 3, 4])
Process finished with exit code 0
defaultdict
使用dict时,如果Key不存在,就会抛出KeyError,如果希望Key不存在时,返回一个默认值,可以使用defaultdit
dd = defaultdict(lambda: 0) # 默认值为0
print(dd['key1'])
dd['key2'] = 1
print(dd['key2'])
0
1
Process finished with exit code 0
OrderedDict
如果要保证Key的顺序,我们可以使用OrderedDict
注意:OrderedDict的Key会按照插入的顺序排列,不是Key的顺序
我们可以用OrderedDict来实现一个FIFO(先进先出)的dict,当dict的容量超出限制时,先删除最早添加的Key
"""
先进先出的dict
"""
from collections import OrderedDict
class LastUpdatedOrderedDict(OrderedDict):
def __init__(self, capacity):
super(LastUpdatedOrderedDict, self).__init__()
self._capacity = capacity
def __setitem__(self, key, value):
contains_key = 1 if key in self else 0
if len(self) - contains_key >= self._capacity:
last = self.popitem(last=False)
print('remove: ', last)
if contains_key:
del self[key]
print('set: ', (key, value))
else:
print('add: ', (key, value))
OrderedDict.__setitem__(self, key, value)
if __name__ == '__main__':
my_dict = LastUpdatedOrderedDict(5)
for i in range(10):
my_dict['i' + str(i)] = i
add: ('i0', 0)
add: ('i1', 1)
add: ('i2', 2)
add: ('i3', 3)
add: ('i4', 4)
remove: ('i0', 0)
add: ('i5', 5)
remove: ('i1', 1)
add: ('i6', 6)
remove: ('i2', 2)
add: ('i7', 7)
remove: ('i3', 3)
add: ('i8', 8)
remove: ('i4', 4)
add: ('i9', 9)
Process finished with exit code 0
Counter
Counter是一个简单的计数器,可以用来实现简单计数功能
eg:统计字符出现的个数
# 统计字符出现的个数
cnt = Counter()
for ch in 'algorithm data structure':
cnt[ch] += 1
print(cnt)
Counter({'t': 4, 'a': 3, 'r': 3, ' ': 2, 'u': 2, 'l': 1, 'g': 1, 'o': 1, 'i': 1, 'h': 1, 'm': 1, 'd': 1, 's': 1, 'c': 1, 'e': 1})
Process finished with exit code 0
base64
Base64是一种常见的二进制编码方法,常用在URL、cookie、网页中传输少量的二进制数据
import base64
print(base64.b64encode(b'binary'))
print(base64.b64decode(b'YmluYXJ5'))
b'YmluYXJ5'
b'binary'
Process finished with exit code 0
urllib
urllib提供了一系列用于操作URL的功能
Get
urllib的request模块可以非常方便地抓取URL的内容,也就是发送一个GET请求到指定的页面,然后返回HTTP的响应
"""
urllib Get
"""
from urllib import request
with request.urlopen('http://www.baidu.com') as f:
data = f.read()
print('Status: ', f.status, f.reason)
for k, v in f.getheaders():
print('%s: %s' % (k, v))
print('Data:\n', data.decode('utf-8'))
Status: 200 OK
Bdpagetype: 1
Bdqid: 0xe44902eb002bb1d7
Cache-Control: private
Content-Type: text/html;charset=utf-8
Date: Fri, 31 Jul 2020 02:27:13 GMT
Expires: Fri, 31 Jul 2020 02:26:27 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Server: BWS/1.1
Set-Cookie: BAIDUID=A29089EC971301B0838A6EF1726749A2:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=A29089EC971301B0838A6EF1726749A2; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1596162433; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BAIDUID=A29089EC971301B045954AE05F8EAC8B:FG=1; max-age=31536000; expires=Sat, 31-Jul-21 02:27:13 GMT; domain=.baidu.com; path=/; version=1; comment=bd
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=32294_1456_32361_32328_32348_32046_32399_32429_32116_32295_26350_31639; path=/; domain=.baidu.com
Traceid: 1596162433065743668216449682322290880983
Vary: Accept-Encoding
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
Connection: close
Transfer-Encoding: chunked
Data:
……
eg:模拟iPhone6去请求豆瓣首页
"""
模拟iPhone6请求豆瓣首页
"""
from urllib import request
req = request.Request('http://www.douban.com/')
# 伪装请求头
req.add_header('User-Agent',
'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) '
'Version/8.0Mobile/10A5376e Safari/8536.25')
with request.urlopen(req) as f:
print('Status: ', f.status, f.reason)
for k, v in f.getheaders():
print("%s: %s" % (k, v))
print('Data: \n', f.read().decode('utf-8'))
Post
如果要以POST发送一个请求,只需要把参数data以bytes形式传入即可
"""
发送Post请求
"""
from urllib import request, parse
data = parse.urlencode([
('enc', 'ca410f208bf8cc391798d68ddfc7a6c8'),
('uuid', '61224959d5fa4575a72b6ca31f1c5eaf')
])
req = request.Request('https://passport2.chaoxing.com/getauthstatus')
req.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 '
'Safari/537.36 Edg/84.0.522.48')
with request.urlopen(req, data=data.encode('utf-8')) as f:
print('Status: ', f.status, f.reason)
for k, v in f.getheaders():
print("%s: %s" % (k, v))
print('Data: ', f.read().decode('utf-8'))
Status: 200 OK
Server: Tengine
Date: Fri, 31 Jul 2020 03:00:20 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 54
Connection: close
Set-Cookie: JSESSIONID=F5C31E54D1A5F9AEE6CAA3CB3E885092; Path=/; HttpOnly
Set-Cookie: route=9614f7ab1993b6f2602cefcb31a2980c;Path=/
Data: {"mes":"二维码已失效","type":"2","status":false}
Process finished with exit code 0