本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 一、常用内置模块 1、datetime Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间 time.time():获取当前时间戳的函数 时间戳:以自从1970年1月1日午夜(历元)到此时此刻的秒数 1、获取当前时间戳 import time nowtime = time.time() print(nowtime) 输出: 1607673559.0851624 2、获取当前日期和时间 datetime模块包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类 import time from datetime import datetime times = datetime.now() print(times) print(type(times)) 输出: 2020-12-11 16:45:44.246725 <class 'datetime.datetime'> 3、获取指定日期和时间 指定某个日期和时间,我们直接用参数构造一个datetime import time from datetime import datetime ktime = datetime(2020,12,11,16,50,49) print(ktime) 输出: 2020-12-11 16:50:49 4、datetime与timestamp的互相转换 全球的timestamp是完全确定的 把datetime转换为timestamp datetime类型转换为timestamp调用timestamp()方法 某些编程语言(如Java和JavaScript)的timestamp使用整数表示毫秒数,这种情况下只需要把timestamp除以1000就得到Python的浮点表示方法 import time from datetime import datetime dt = datetime(2020,12,11,17,00,26,56) print(dt.timestamp()) 输出: 1607677226.000056 把datetime转换为timestamp timestamp转换为datetime,使用datetime提供的fromtimestamp()方法 from datetime import datetime t = 1429417200.0 print(datetime.fromtimestamp(t)) 输出: 2015-04-19 12:20:00 timestamp也可以直接被转换到UTC标准时区的时间: from datetime import datetime t = 1429417200.0 print(datetime.fromtimestamp(t)) # 本地时间 2015-04-19 12:20:00 print(datetime.utcfromtimestamp(t)) # UTC时间 2015-04-19 04:20:00 5、str与datetime的互相转换 str转换为datetime 用户输入的日期和时间是字符串,处理日期和时间,首先必须把str转换为datetime,通过datetime.strptime()实现,日期和时间的格式化字符串 字符串’%Y-%m-%d %H:%M:%S’规定了日期和时间部分的格式 import time from datetime import datetime cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S') print(cday) 输出: 2015-06-01 18:19:59 datetime转换为str datetime转换为str是通过strftime()实现 import time from datetime import datetime now = datetime.now() print(now.strftime('%a, %b, %d, %H:%M')) 输出: Sat, Dec, 12, 15:24 6、datetime加减 datetime的加减就是对日期和时间向前或向后计算的到新的datetime datetime加减可以直接用+和-运算 import datetime today = datetime.date.today() print(today) tomorrow = today + datetime.timedelta(days=1) print(tomorrow) 输出: 2020-12-12 2020-12-13 from datetime import datetime, timedelta now = datetime.now() print(now) renow = now - timedelta(hours=18) print(renow) 输出: 2020-12-12 16:31:05.391746 2020-12-11 22:31:05.391746 7、本地时间装换为UTC时间 UTC时间指UTC+0:00时区的时间 datetime类型有一个时区属性tzinfo,默认为None导致无法区分这个datetime是哪个时区,可以给datetime加上时区 from datetime import datetime, timedelta, timezone tz_utc_5 = timezone(timedelta(hours=5)) #创建时区UTC+5 now = datetime.now() print(now) dt = now.replace(tzinfo=tz_utc_5) print(dt) 输出: 2020-12-12 16:58:16.337391 2020-12-12 16:58:16.337391+05:00 8、时区转换 时区转换的关键在于,拿到一个datetime时,要获知其正确的时区,然后强制设置时区 用带时区的datetime,通过astimezone()方法,可以转换到任意时区 from datetime import datetime, timedelta, timezone utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc) print(utc_dt) bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8))) print(bj_dt) 2、collections collections是Python内建的一个集合模块,提供了许多有用的集合类 1、namedtuple函数 namedtuple函数,它用来创建一个自定义的tuple对象,规定了tuple元素的个数,可以用属性引用tuple的某个元素 namedtuple定义一种数据类型,它具备tuple的不变性,根据属性来引用,使用十分方便 from collections import namedtuple Point = namedtuple('point',['x', 'y']) p = Point(1, 2) print(p.x) print(p.y) print(isinstance(p, Point)) print(isinstance(p, tuple)) 输出: 1 2 True True 2、deque双向列表 deque可以实现快速的删除和插入,适合队列和栈 list虽然按照索引查找很快,但是由于list是线性存储,删除和插入时很慢 deque实现list的append()和pop(),还支持appendleft()和popleft(),这样就可以往头部添加和删除数据了 from collections import deque q = deque(['a', 'b', 'c']) q.append('x') q.appendleft('y') print(q) 输出: deque(['y', 'a', 'b', 'c', 'x']) 3、defaultdict 正常访问dict的key,当没有该访问的key时会报错,这是用defaultdict就可以返回一个特定的值 注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入 from collections import defaultdict dd = defaultdict(lambda : 'A/N') dd['key1'] = 'abc' print(dd['key1']) print(dd['key2']) 输出: abc A/N 4、OrderedDict dict的key是无序的,在迭代dict时并不知道其顺序,可以用OrderedDict保持其顺序 OrderedDict的Key会按照插入的顺序排列,不是Key本身排序 from collections import OrderedDict d = dict([('a', 1), ('b', 2), ('c', 3)]) print(d) od = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(od) od['z'] = 1 od['y'] = 2 od['x'] = 3 print(list(od.keys())) # 按照插入的Key的顺序返回 输出: {'a': 1, 'b': 2, 'c': 3} OrderedDict([('a', 1), ('b', 2), ('c', 3)]) ['a', 'b', 'c', 'z', 'y', 'x'] OrderedDict可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key from collections import OrderedDict class LastUpdateOrderedDict(OrderedDict): def __init__(self, capacity): super(LastUpdateOrderedDict, self).__init__() self._capacity = capacity def __setitem__(self, key, value): containsKey = 1 if key in self else 0 if len(self) - containsKey >= self._capacity: last = self.popitem(last=False) print('remove:',last) if containsKey: del self[key] print('set:', (key, value)) else: print('add:', (key, value)) OrderedDict.__setitem__(self, key, value) 5、ChainMap ChainMap可以把一组dict串起来并组成一个逻辑上的dict ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找 查找user和color这两个参数 from collections import ChainMap import os, argparse # 构造缺省参数: defaults = { 'color': 'red', 'user': 'guest' } # 构造命令行参数: parser = argparse.ArgumentParser() parser.add_argument('-u', '--user') parser.add_argument('-c', '--color') namespace = parser.parse_args() command_line_args = { k: v for k, v in vars(namespace).items() if v } # 组合成ChainMap: combined = ChainMap(command_line_args, os.environ, defaults) # 打印参数: print('color=%s' % combined['color']) print('user=%s' % combined['user']) 输出: (base) F:\pycharm\project>python test.py color=red user=guest (base) F:\pycharm\project>python test.py -u yang color=red user=yang (base) F:\pycharm\project>python test.py -u yang -c yellow color=yellow user=yang 6、counter 简单的计数器 counter是一个dict from collections import Counter c = Counter() for ch in 'programming': c[ch] = c[ch]+1 print(c) c.update('hello') print(c) 输出: Counter({'r': 2, 'g': 2, 'm': 2, 'p': 1, 'o': 1, 'a': 1, 'i': 1, 'n': 1}) Counter({'r': 2, 'o': 2, 'g': 2, 'm': 2, 'l': 2, 'p': 1, 'a': 1, 'i': 1, 'n': 1, 'h': 1, 'e': 1}) 3、base64方法 Base64是一种用64个字符来表示任意二进制数据的方法,是一种最常见的二进制编码方法 一个包含64个字符的数组 对二进制数据进行处理,每3个字节一组,一共是3x8=24bit,划为4组,每组正好6个bit 得到4个数字作为索引,然后查表,获得相应的4个字符,就是编码后的字符串 Python内置的base64可以直接进行base64的编解码 import base64 print(base64.b64encode(b'binary\x00string')) 输出: b'YmluYXJ5AHN0cmluZw==' 标准的Base64编码可能出现字符+和/,URL中不能直接作为参数,有一种'url safe'的base64编码,就是把字符+和/分别变成-和_ import base64 print(base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')) 输出: b'abcd++//' import base64 print(base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')) 输出: b'abcd--__' > Base64是通过查表的编码方法,不能用于加密,即使使用自定义的编码表也不行 Base64适用于小段内容的编码,比如数字证书签名、Cookie的内容等 由于=字符可能出现在Base64编码中,=用在URL、Cookie里面会造成歧义,很多Base64编码后会把=去掉 Base64是把3个字节变为4个字节,Base64编码的长度永远是4的倍数,需要加上=把Base64字符串的长度变为4的倍数,才能正常解码 4、struct Python提供了一个struct模块来解决bytes和其他二进制数据类型的转换 struct的pack函数把任意数据类型变成bytes 表示字节顺序是big-endian,也就是网络序,I表示4字节无符号整数 import struct print(struct.pack('>I', 10240099)) 输出: b'\x00\x9c@c' unpack把bytes变成相应的数据类型 import struct struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80') 输出: (4042322160, 32896) 5、hashlib摘要算法 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等 摘要算法又称哈希算法、散列算法:它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示) 摘要函数为单向函数,计算f(data)很容易,但通过digest反推data却非常困难 摘要算法MD5 MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示 import hashlib md5 = hashlib.md5() md5.update('how to use md5 in python hashlib?'.encode('utf-8')) print(md5.hexdigest()) print(len(md5.hexdigest())) 输出: d26a53750bc40b38b65a520292f69306 32 摘要算法SHA1 SHA1的结果是160 bit字节,通常用一个40位的16进制字符串 import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in '.encode('utf-8')) sha1.update('python hashlib?'.encode('utf-8')) print(sha1.hexdigest()) 输出: 2c76b57293ce30acef38d98f6046927161b46a44 6、itertools Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数 itertools提供的几个“无限”迭代器 import itertools natuals = itertools.count(1) for n in natuals: print(n) 输出: ... 1 2 3 ... cycle()会把传入的一个序列无限重复下去 import itertools cs = itertools.cycle('ABC') # 注意字符串也是序列的一种 for c in cs: print(c) 输出: ... 'A' 'B' 'C' 'A' 'B' 'C' ... repeat()负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数 import itertools ns = itertools.repeat('A', 3) for n in ns: print(n) 输出: A A A chain()可以把一组迭代对象串联起来,形成一个更大的迭代器 import itertools for c in itertools.chain('ABC', 'XYZ'): print(c) 输出: A B C X Y Z groupby()把迭代器中相邻的重复元素挑出来放在一起 import itertools for key, group in itertools.groupby('AAABBBCCAAA'): print(key, list(group)) 输出: A ['A', 'A', 'A'] B ['B', 'B', 'B'] C ['C', 'C'] A ['A', 'A', 'A'] 挑选规则是通过函数完成,作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组,函数返回值作为组的key,忽略大小写分组,可以让元素’A’和’a’都返回相同的key import itertools for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()): print(key, list(group)) 输出: A ['A', 'a', 'a'] B ['B', 'B', 'b'] C ['c', 'C'] A ['A', 'A', 'a'] 二、常用外置模块 1、requests Python第三方库requests比python的内置库urllib处理URL资源更方便 1、使用requests GET访问一个页面 当获取的首页乱码时,可以用encoding/content设置解码方式 import requests r = requests.get('https://www.baidu.com/') #用encoding解码获取的内容 r.encoding='utf-8' #设置编码方式 print(r.encoding) #检测编码方式 print(r.status_code) #状态码判断请求是否成功 print(r.text) #文本内容 print(r.url) #实际请求的url #用content解码获取的内容 r.content.decode() #用content获得bytes对象并用decode解码 print(r.text) 可以用来判断请求是否成功 assert response.status_code==(num) 查看请求的响应头以及相应的url import requests response = requests.get('https://www.sina.com') print(response.headers) print(response.request.url) print(response.url) 可以构造正确的headers头部,来请求网页得到完整的页面内容 import requests headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'} response = requests.get('https://www.baidu.com',headers = headers) print(response.headers) print(response.content.decode()) 在requests中的response.requests.url的返回结果中存在url编码,需要url解码 import requests headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'} p = {'wd':'耐克'} url_tem = 'https://www.baidu.com/s?' r = requests.get(url_tem,headers = headers, params = p) print(r.status_code) print(r.request.url) #返回结果存在url编码 print(r.content) print(r.text) 爬取耐克百度贴吧的网页信息,并保存到本地 import requests class TiebaSpider: def __init__(self,tiebaname): self.tiebaname = tiebaname self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'} self.url_temp = 'https://tieba.baidu.com/f?kw='+tiebaname+'&ie=utf-8&pn={}' def get_url_list(self): url_list =[] for i in range(1000): url_list.append(self.url_temp.format(i*50)) return url_list def parse_url(self,url): response = requests.get(url,headers = self.headers) return response.content.decode() def html_save(self,html_str,pagename): file_path = '{}第{}页.html'.format(self.tiebaname,pagename) with open(file_path,'w',encoding='utf-8') as f: f.write(html_str) def run(self): get_list = self.get_url_list() for url in get_list: html_str = self.parse_url(url) pagename = get_list.index(url)+1 save = self.html_save(html_str,pagename) if __name__ == '__main__': tieba_spaider = TiebaSpider('耐克') tieba_spaider.run() |
|