一、random模块
1、random模块用法
1
2
3
4
5
6
7
8
9
10
|
import
random
print
(random.random())
# 打印大于0且小于1之间的一个小数
print
(random.randint(
1
,
3
))
# 打印大于等于1且小于等于3之间的一个整数
print
(random.randrange(
1
,
3
))
# 打印大于等于1且小于3之间的一个整数
print
(random.choice([
1
,
'23'
, [
4
,
5
]]))
# 结果为1或者23或者[4,5]
print
(random.sample([
1
,
'23'
, [
4
,
5
]],
2
))
# 打印列表元素任意2个组合
print
(random.uniform(
1
,
3
))
# 打印大于1小于3的小数
item
=
[
1
,
3
,
5
,
7
,
9
]
random.shuffle(item)
# 打乱item的顺序,相当于"洗牌",如[9, 1, 7, 3, 5]
print
(item)
|
2、生成随机验证码
1
2
3
4
5
6
7
8
9
|
import
random
def
make_code(n):
#n表示验证码的位数
res
=
''
for
i
in
range
(n):
#传参数,表示生成多少位的验证码
s1
=
chr
(random.randint(
65
,
90
))
#对应ASCII码的数字,再取到对应字母
s2
=
str
(random.randint(
0
,
9
))
#0到9的数字随机取一个
res
+
=
random.choice([s1,s2])
#对s1,s2的值进行随机取一个值,取到的字符串不断相加
return
res
print
(make_code(
9
))
|
二、os模块
1、os模块的用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import
os
os.getcwd()
#获取当前工作目录,即当前python脚本工作的目录路径
os.chdir(
"dirname"
)
#改变当前脚本工作目录;切换目录
os.curdir
#返回当前目录: ('.')
os.pardir
#获取当前目录的父目录字符串名:('..')
os.makedirs(
'dirname1/dirname2'
)
#可生成多层递归目录
os.removedirs(
'dirname1'
)
#若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir(
'dirname'
)
#生成单级目录;
os.rmdir(
'dirname'
)
#删除单级空目录,若目录不为空则无法删除,报错;
os.listdir(
'dirname'
)
#列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()
#删除一个文件
os.rename(
"oldname"
,
"newname"
)
#重命名文件/目录
os.stat(
'path/filename'
)
#获取文件/目录信息
os.sep
#输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep
#输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
os.pathsep
#输出用于分割文件路径的字符串 win下为分号;,Linux下为冒号:
os.name
#输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system(
"bash command"
)
#运行shell命令,直接显示,所以取不到我们想要的返回值
os.environ
#获取系统环境变量
os.path.abspath(path)
#返回path规范化的绝对路径
os.path.split(path)
#将path分割成目录和文件名二元组返回
os.path.dirname(path)
#返回path的目录。即是os.path.split(path)的第一个元素
os.path.basename(path)
#返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)
#如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)
#如果path是绝对路径,返回True
os.path.isfile(path)
#如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)
#如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])
#将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)
#返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)
#返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path)
#返回path的大小
|
2、跨平台相关用法
1
2
3
4
5
6
7
8
|
在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
os.path.normcase(
'c:/windows\\system32\\'
)
print
(os.path.normcase(
'c:/windows\\system32\\'
))
#打印结果c:\windows\system32\
规范化路径,如..和
/
os.path.normpath(
'c://windows\\System32\\../Temp/'
)
print
(os.path.normpath(
'c://windows\\System32\\../Temp/'
))
#打印结果c:\windows\Temp
a
=
'/Users/test1/\\\a1/\\\\aa.py/../..'
print
(os.path.normpath(a))
#打印结果\Users\test1
|
3、os路径处理
1
2
3
4
5
6
7
8
9
10
|
#方式一:
import
os
print
(os.path.normpath(os.path.join(
os.path.abspath(__file__),
#取到当前文件的绝对路径
'..'
,
#取上一级目录
'..'
#取上一级目录
)
))
#方式二:
print
(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
三、sys模块
1、sys模块的用法
import sys
sys.argv #命令行参数List,第一个元素是程序本身路径,执行脚本会得到所有的参数
sys.exit(n) #退出程序,正常退出时exit(0)
sys.version #获取Python解释程序的版本信息
sys.maxint #最大的Int值
sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform #返回操作系统平台名称
2、打印进度条
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
print
(
'[%-50s]'
%
'#'
) #指定宽度为
50
,左对齐,结果[# ]
print
((
'[%%-%ds]'
%
50
))
#%%表示取消%的特殊意义,结果[%-50s]
print
((
'[%%-%ds]'
%
50
)
%
'#'
) #结果[# ]
print
((
'[%%-%ds]'
%
50
)
%
(
'#'
*
5
)) #结果[##### ]
#完整代码如下:
import
sys
import
time
def
progress(percent,width
=
50
):
if
percent >
=
1
:
#百分比大于1让其强制等于1,否则会超过百分之百
percent
=
1
show_str
=
(
'[%%-%ds]'
%
width)
%
(
int
(width
*
percent)
*
'#'
)
print
(
'\r%s %d%%'
%
(show_str,
int
(
100
*
percent)),
file
=
sys.stdout,flush
=
True
,end
=
'')
#\r表示跳到行首
#模拟数据下载:
data_size
=
102511
#文件总大小
recv_size
=
0
#接收文件大小
while
recv_size < data_size:
time.sleep(
0.1
)
# 模拟数据的传输延迟
recv_size
+
=
1024
# 每次收1024
percent
=
recv_size
/
data_size
# 接收的比例
progress(percent, width
=
70
)
# 进度条的宽度70
|
四、shutil模块
1、shutil模块用法
1
2
3
4
5
6
7
8
9
10
11
|
import
shutil
shutil.copyfileobj(
open
(
'old.xml'
,
'r'
),
open
(
'new.xml'
,
'w'
))
#将文件内容拷贝到另一个文件中
shutil.copyfile(
'f1.log'
,
'f2.log'
)
# 拷贝文件,目标文件无需存在
shutil.copymode(
'f1.log'
,
'f2.log'
)
# 仅拷贝权限。内容、组、用户均不变,目标文件必须存在
shutil.copystat(
'f1.log'
,
'f2.log'
)
# 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags,目标文件必须存在
shutil.copy(
'f1.log'
,
'f2.log'
)
#拷贝文件和权限
shutil.copy2(
'f1.log'
,
'f2.log'
)
#拷贝文件和状态信息
shutil.copytree(
'folder1'
,
'folder2'
,ignore
=
shutil.ignore_patterns(
'*.pyc'
,
'tmp*'
))
# 递归的去拷贝文件夹,目标目录不能存在,ignore的意思是排除
shutil.copytree(
'f1'
,
'f2'
, symlinks
=
True
, ignore
=
shutil.ignore_patterns(
'*.pyc'
,
'tmp*'
))
#拷贝软链接,
shutil.rmtree(
'folder1'
)
#递归的去删除文件
shutil.move(
'folder1'
,
'folder3'
)
#递归的去移动文件,其实就是重命名
|
2、压缩文件
1
2
3
4
5
6
|
(
1
) 将
/
data 下的文件打包放置当前程序目录
import
shutil
ret
=
shutil.make_archive(
"data_bak"
,
'gztar'
, root_dir
=
'/data'
)
(
2
)将
/
data下的文件打包放置
/
tmp
/
目录
import
shutil
ret
=
shutil.make_archive(
"/tmp/data_bak"
,
'gztar'
, root_dir
=
'/data'
)
|
五、json&pickle模块
1、序列化
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等
作用是:(1)持久保存状态
(2)跨平台数据交互
2、json模块用法
1
2
3
4
5
6
7
8
9
|
dic
=
{
'wang'
:{
'password'
:
'123'
,
'sex'
:
'male'
},
'li'
:{
'password'
:
'123'
,
'sex'
:
'male'
},
}
import
json
json.dump(dic,
open
(r
'C:\Users\db\db.json'
,
'w'
))
#会将数据按照json的格式写入文件db.json
json.load(
open
(r
'C:\Users\db\db.json'
,
'r'
))
#取到db.json里面的数据
#
#无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
|
3、pickle模块用法
1
2
3
4
5
|
import
pickle
pickle.dump(dic,
open
(r
'C:\Users\db\db.json'
,
'wb'
))
pickle.load(
open
(r
'C:\Users\db\db.json'
,
'rb'
))
#
#pickle的用法和json差不多,不过读写是bytes类型
|
六、shelve模块
shelve模块只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
1
2
3
4
5
6
7
|
import
shelve
f
=
shelve.
open
(r
'sheve.txt'
)
f[
'stu1_info'
]
=
{
'name'
:
'wang'
,
'age'
:
18
,
'hobby'
:[
'smoking'
,
'drinking'
]}
f[
'stu2_info'
]
=
{
'name'
:
'gangdan'
,
'age'
:
53
}
f[
'school_info'
]
=
{
'website'
:
'http://www.pypy.org'
,
'city'
:
'beijing'
}
print
(f[
'stu1_info'
][
'hobby'
])
f.close()
|
七、xml模块
如下一个xml文件a.xml:
<?xml version="1.0"?>
<data v="1.0">
hello world
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
1、xml模块的用法
1
2
3
4
5
6
7
|
from
xml.etree
import
ElementTree
tree
=
ElementTree.parse(
'a.xml'
)
root
=
tree.getroot()
print
(root)
#<Element 'data' at 0x0000000001E0ACC8>
print
(root.tag)
#得到标签的名字 data
print
(root.attrib)
#标签的属性{'v': '1.0'}
print
(root.text)
#标签的内容hello world
|
2、查找方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
(
1
)从子节点中查找
print
(root.find(
'country'
))
#<Element 'country' at 0x0000000001E6CC28>
print
(root.findall(
'country'
))
#[<Element 'country' at 0x00000000027ECC28>, <Element 'country' at 0x0000000002A62C78>, <Element 'country' at 0x0000000002A62E08>]
print
(root.find(
'rank'
))
#None
直接查找rank返回
None
,要实现找到rank,需要借助脚本:
from
xml.etree
import
ElementTree
tree
=
ElementTree.parse(
'a.xml'
)
root
=
tree.getroot()
for
country
in
root.findall(
'country'
):
rank
=
country.find(
'rank'
)
print
(rank.tag,rank.attrib,rank.text)
'''
#执行结果是:
rank {'updated': 'yes'} 2
rank {'updated': 'yes'} 5
rank {'updated': 'yes'} 69
'''
(
2
)从整个树形结构中查找
print
(
list
(root.
iter
(
'rank'
)))
#[<Element 'rank' at 0x0000000002A1B598>, <Element 'rank' at 0x0000000002A53CC8>, <Element 'rank' at 0x0000000002A53E58>]
|
3、遍历整个文档
1
2
3
4
5
6
|
for
country
in
root:
print
(country.attrib[
'name'
])
for
item
in
country:
print
(item.tag,item.attrib,item.text)
for
year
in
root.
iter
(
'year'
):
#在整个文档中找year
print
(year.tag,year.attrib,year.text)
|
4、修改文件中的内容
1
2
3
4
|
for
year
in
root.
iter
(
'year'
):
year.
set
(
'updated'
,
'yes'
)
year.text
=
str
(
int
(year.text)
+
1
)
#年份加1
tree.write(
'b.xml'
)
#结果写到新文件b.xml,也可以直接修改到源文件a.xml
|
5、添加新内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
for
country
in
root:
obj
=
ElementTree.Element(
'admin'
)
obj.attrib
=
{
'name'
:
'wang'
,
'age'
:
'18'
}
obj.text
=
'hello,wang'
country.append(obj)
#添加进文件
tree.write(
'b.xml'
)
#写入文件,所有的country下面都添加了<admin age="18" name="wang">hello,wang</admin></country>
添加到固定位置:
for
rank
in
root.
iter
(
'rank'
):
if
int
(rank.text)
=
=
5
:
#只在rank值为5的地方添加
obj
=
ElementTree.Element(
'admin'
)
obj.attrib
=
{
'name'
:
'wang'
,
'age'
:
'18'
}
obj.text
=
'hello,wang'
rank.append(obj)
tree.write(
'b.xml'
)
|
八、configparser模块
有如下文件a.cfg,在C:\Users\a.cfg
[mysql]
user=root
password=123456
[mysqld]
port=3306
1、读取文件中的数据
1
2
3
4
5
6
7
8
9
10
|
import
configparser
config
=
configparser.ConfigParser()
config.read(r
'C:\Users\a.cfg'
)
print
(config.sections())
#查看所有标题 ['mysql', 'mysqld']
print
(config.options(
'mysql'
))
#得到sections下对应的options的key,['user', 'password']
print
(config.items(
'mysql'
))
#[('user', 'root'), ('password', '123456')]
val
=
config.get(
'mysql'
,
'user'
)
#得到key对应的值,结果是 root
print
(val)
print
(config.getint(
'mysql'
,
'age'
))
#取的值是整型
print
(config.getfloat(
'mysql'
,
'age'
))
#取的值是浮点型
|
2、修改文件中的数据
1
2
3
4
5
6
7
8
9
10
11
|
import
configparser
config
=
configparser.ConfigParser()
config.read(
'a.cfg'
,encoding
=
'utf-8'
)
config.remove_section(
'mysqld'
)
#删除整个标题mysqld
config.remove_option(
'mysqld'
,
'port'
)
#删除标题mysqld下的port
print
(config.has_section(
'mysqld'
))
#判断是否存在mysqld标题
print
(config.has_option(
'mysql'
,
'user'
))
#判断标题mysql下是否有user
config.add_section(
'admin'
)
#添加一个标题admin
config.
set
(
'admin'
,
'name'
,
'wang'
)
#在标题admin下添加name=wang,age=18的配置
config.
set
(
'admin'
,
'age'
,
'18'
)
#添加的必须是字符串
config.write(
open
(
'a.cfg'
,
'w'
))
#最后将修改的内容写入文件,完成最终的修改
|
基于上述方法添加一个ini文档:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import
configparser
config
=
configparser.ConfigParser()
config[
"DEFAULT"
]
=
{
'ServerAliveInterval'
:
'45'
,
'Compression'
:
'yes'
,
'CompressionLevel'
:
'9'
}
config[
'bitbucket.org'
]
=
{}
config[
'bitbucket.org'
][
'User'
]
=
'hg'
config[
'topsecret.server.com'
]
=
{}
topsecret
=
config[
'topsecret.server.com'
]
topsecret[
'Host Port'
]
=
'50022'
topsecret[
'ForwardX11'
]
=
'no'
config[
'DEFAULT'
][
'ForwardX11'
]
=
'yes'
with
open
(
'example.ini'
,
'w'
) as configfile:
config.write(configfile)
#结果是生成文件:example.ini
[DEFAULT]
serveraliveinterval
=
45
compression
=
yes
compressionlevel
=
9
forwardx11
=
yes
[bitbucket.org]
user
=
hg
[topsecret.server.com]
host port
=
50022
forwardx11
=
no
|
九、hashlib模块
1、介绍
hash:一种算法 ,python3里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
有三个特点:
(1)内容相同则hash运算结果相同,内容稍微改变则hash值则变
(2)不可逆推
(3)相同算法:无论校验多长的数据,得到的哈希值长度固定。
2、hashlib模块用法
1
2
3
4
5
6
7
8
9
10
|
import
hashlib
m
=
hashlib.md5()
# m=hashlib.sha256()
m.update(
'hello'
.encode(
'utf8'
))
print
(m.hexdigest())
# 5d41402abc4b2a76b9719d911017c592
m.update(
'world'
.encode(
'utf8'
))
print
(m.hexdigest())
# fc5e038d38a57032085441e7fe7010b0
m2
=
hashlib.md5()
m2.update(
'helloworld'
.encode(
'utf8'
))
print
(m2.hexdigest())
# fc5e038d38a57032085441e7fe7010b0
|
注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
这样update多次就为校验大文件提供了可能。
3、密码加密
(1)为防止撞库反解出密码。所以,有必要对加密算法中添加自定义key再来做加密
1
2
3
4
|
import
hashlib
hash
=
hashlib.sha256(
'w123q321'
.encode(
'utf8'
))
#加密(加盐),增加密码破解难度
hash
.update(
'helloworld'
.encode(
'utf8'
))
print
(
hash
.hexdigest())
# d11039095aafd7cb72f6681aab9d55e5eff453940287e9799fdb52e09fef170c
|
(2)python还有一个hmac模块,它内部对我们创建key和内容进行进一步的处理然后再加密:
1
2
3
4
|
import
hmac
h
=
hmac.new(
'hello'
.encode(
'utf8'
))
h.update(
'world'
.encode(
'utf8'
))
print
(h.hexdigest())
#0e2564b7e100f034341ea477c23f283b
|
注意:要想保证hmac最终结果一致,必须保证
# 1:hmac.new括号内指定的初始key一样
# 2:无论update多少次,校验的内容累加到一起是一样的内容
4、模拟撞库破解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import
hashlib
passwds
=
[
#猜测用户可能的密码
'alex3714'
,
'alex123'
,
'alex123456'
,
'123456'
,
'1234567890'
,
'a123456'
,
]
def
make_passwd_dic(passwds):
dic
=
{}
for
passwd
in
passwds:
m
=
hashlib.md5()
m.update(passwd.encode(
'utf-8'
))
dic[passwd]
=
m.hexdigest()
return
dic
#dic得到的是原始密码和加密密码的键值对
def
break_code(cryptograph,passwd_dic):
for
k,v
in
passwd_dic.items():
if
v
=
=
cryptograph:
print
(
'密码是===>\033[46m%s\033[0m'
%
k)
cryptograph
=
'aee949757a2e698417463d47acac93df'
#抓包得到的加密后的密码
break_code(cryptograph,make_passwd_dic(passwds))
|
十、subprocess模块
1、subprocess模块用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import
time
import
subprocess
subprocess.Popen(
'tasklist'
,shell
=
True
,
stdout
=
subprocess.PIPE,
stderr
=
subprocess.PIPE,
)
#交给子进程执行,不等子进程返回结果就执行后面的代码
print
(subprocess.Popen(
'tasklist'
,shell
=
True
) )
time.sleep(
1
)
#打印到终端的有我们需要的数据,不加这行结果只是<subprocess.Popen object at 0x00000000021F88D0>
最终代码为:
import
subprocess
obj
=
subprocess.Popen(
'tasklist'
,shell
=
True
,
stdout
=
subprocess.PIPE,
stderr
=
subprocess.PIPE,
)
print
(obj.stdout.read().decode(
'gbk'
))
|
2、subprocess模块实例
(1)实例一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
'''
sh-3.2# ls /Users/egon/Desktop |grep txt$
mysql.txt
tt.txt
事物.txt
'''
import
subprocess
res1
=
subprocess.Popen(
'ls /Users/jieli/Desktop'
,shell
=
True
,stdout
=
subprocess.PIPE)
res
=
subprocess.Popen(
'grep txt$'
,shell
=
True
,stdin
=
res1.stdout,
stdout
=
subprocess.PIPE)
print
(res.stdout.read().decode(
'utf-8'
))
#等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
res1
=
subprocess.Popen(
'ls /Users/jieli/Desktop |grep txt$'
,shell
=
True
,stdout
=
subprocess.PIPE)
print
(res1.stdout.read().decode(
'utf-8'
))
windows下:
# dir | findstr 'test*'
# dir | findstr 'txt$'
import
subprocess
res1
=
subprocess.Popen(r
'dir C:\Users\Administrator\Desktop'
,shell
=
True
,stdout
=
subprocess.PIPE)
res
=
subprocess.Popen(
'findstr txt'
,shell
=
True
,stdin
=
res1.stdout,
stdout
=
subprocess.PIPE)
#过滤包含txt字符的文件
print
(res.stdout.read().decode(
'gbk'
))
#得到结果为bytes类型,在windows下需要用gbk解码
|
(2)实例二:得到关于python的进程信息
1
2
3
4
5
6
7
8
9
10
|
obj1
=
subprocess.Popen(
'tasklist'
,shell
=
True
,
stdout
=
subprocess.PIPE,
stderr
=
subprocess.PIPE,
)
obj2
=
subprocess.Popen(
'findstr python'
,shell
=
True
,
#过滤有python字符串的行
stdin
=
obj1.stdout,
stdout
=
subprocess.PIPE,
stderr
=
subprocess.PIPE,
)
print
(obj2.stdout.read())
|