一、glob模块
glob是python自己带的一个文件操作相关模块,
用它可以查找符合自己目的的文件,类似于Windows下的文件搜索,
支持通配符操作,*,?,[]这三个通配符,
*代表0个或多个字符,
?代表一个字符,
[]匹配指定范围内的字符,如[0-9]匹配数字。
两个主要方法如下。
1. glob方法:
glob模块的主要方法就是glob,该方法返回所有匹配的文件路径列表(list);
该方法需要一个参数用来指定匹配的路径字符串(字符串可以为绝对路径也可以为相对路径),
其返回的文件名只包括当前目录里的文件名,不包括子文件夹里的文件。
比如:
glob.glob(r’c:*.txt’)
我这里就是获得C盘下的所有txt文件
glob.glob(r’E:\pic**.jpg’)
获得指定目录下的所有jpg文件
使用相对路径:
glob.glob(r’../*.py’)
import glob
print(glob.glob('/etc/*.conf'))
['/etc/resolv.conf', '/etc/fuse.conf', '/etc/mtools.conf', '/etc/hba.conf', '/etc/extlinux.conf', '/etc/libuser.conf', '/etc/host.conf', '/etc/sos.conf', '/etc/idmapd.conf', '/etc/sestatus.conf', '/etc/ld.so.conf', '/etc/nsswitch.conf', '/etc/softhsm2.conf', '/etc/slp.conf', '/etc/libaudit.conf', '/etc/request-key.conf', '/etc/krb5.conf', '/etc/asound.conf', '/etc/dracut.conf', '/etc/yum.conf', '/etc/e2fsck.conf', '/etc/mke2fs.conf', '/etc/logrotate.conf', '/etc/locale.conf', '/etc/tcsd.conf', '/etc/fprintd.conf', '/etc/sysctl.conf', '/etc/man_db.conf', '/etc/pbm2ppa.conf', '/etc/cgconfig.conf', '/etc/cgrules.conf', '/etc/wvdial.conf', '/etc/cgsnapshot_blacklist.conf', '/etc/updatedb.conf', '/etc/dnsmasq.conf', '/etc/rsyncd.conf', '/etc/ant.conf', '/etc/Trolltech.conf', '/etc/ipsec.conf', '/etc/kdump.conf', '/etc/pnm2ppa.conf', '/etc/numad.conf', '/etc/autofs.conf', '/etc/autofs_ldap_auth.conf', '/etc/oddjobd.conf', '/etc/vconsole.conf', '/etc/usb_modeswitch.conf', '/etc/chrony.conf', '/etc/ksmtuned.conf', '/etc/sudo.conf', '/etc/ntp.conf', '/etc/dleyna-server-service.conf', '/etc/nfsmount.conf', '/etc/radvd.conf', '/etc/named.conf', '/etc/rsyslog.conf', '/etc/sudo-ldap.conf', '/etc/pcp.conf', '/etc/brltty.conf', '/etc/lftp.conf']
2. iglob方法:
获取一个迭代器( iterator )对象,使用它可以逐个获取匹配的文件路径名。
与glob.glob()的区别是:glob.glob同时获取所有的匹配路径,而 glob.iglob一次只获取一个匹配路径。
下面是一个简单的例子:
父目录中所有的.py文件
import glob
res = glob.iglob('/etc/**.conf')
for i in res:
print(i,end=' ')
/etc/resolv.conf /etc/fuse.conf /etc/mtools.conf /etc/hba.conf /etc/extlinux.conf /etc/libuser.conf /etc/host.conf
res是一个迭代器对象,通过遍历,可以输出所有满足条件的*.conf文件
二、正则表达式
正则表达式是一种用来匹配字符串的强有力的武器。
它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
findall方法
# 导入re模块, regular expression, 才能使用正则表达式;
import re
# 字符串;
s = 'westosshellwestos'
# 正则表达式自定义的规则, 查找westos这个字符串;
regular = r'westos'
# findall函数, 第一个参数是规则, 第二个参数是需要查找的字符串内容;
# 返回的是满足规则的所有内容, 是一个列表;
print(re.findall(regular,s))
match方法
import re
s = 'westosshellwestos'
regular = r'westos'
# match方法是从左向右依次匹配,;
# 如果匹配到, 返回一个Match对象, 通过该对象的group方法, 获取匹配的值;
# 如果没有匹配到, 返回一个None, 没有group方法;
matchObj = re.match(regular,s)
# 判断是否有匹配到内容;
if matchObj:
print("匹配内容为:%s" %(matchObj.group()))
else:
print("未匹配到内容")
1.正则表达式特殊符号
# 匹配单个字符---特殊符号:
\d: 单个数字 ===== [[:digit:]]
\s: 单个空格 ===== [[:space:]]
\w:匹配单个字母, 数字或者下划线
\D: 除了单个数字
\S: 除了单个空格
\W: 除了匹配单个字母, 数字或者下划线
数字与非数字
import re
print(re.match(r'\d','1').group())
print(re.match(r'\d','qha'))
print(re.match(r'\d','124').group())
print(re.match(r'\D','qha').group())
print(re.match(r'\D','124'))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/01_正则表达式.py
1
None
1
q
None
空格与非空格(空格是广义的, 包括:\n, \t, \r, ’ ‘)
print(re.match(r'\s',' hello'))
print(re.match(r'\s','\thello'))
print(re.match(r'\s','\nhello'))
print(re.match(r'\s','\rhello'))
print(re.match(r'\S','\rhrllo'))
print(re.match(r'\S','23\rhello'))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/01_正则表达式.py
<_sre.SRE_Match object; span=(0, 1), match=' '>
<_sre.SRE_Match object; span=(0, 1), match='\t'>
<_sre.SRE_Match object; span=(0, 1), match='\n'>
<_sre.SRE_Match object; span=(0, 1), match='\r'>
None
<_sre.SRE_Match object; span=(0, 1), match='2'>
字母数字或下划线
print(re.match(r'\w', 'wfkrlgtr'))
print(re.match(r'\w', '12wfkrlgtr'))
print(re.match(r'\w', '_12wfkrlgtr'))
print(re.match(r'\w', '@12wfkrlgtr'))
print(re.match(r'\W', '@12wfkrlgtr'))
<_sre.SRE_Match object; span=(0, 1), match='w'>
<_sre.SRE_Match object; span=(0, 1), match='1'>
<_sre.SRE_Match object; span=(0, 1), match='_'>
None
<_sre.SRE_Match object; span=(0, 1), match='@'>
其他
# [ab] == a或者b
# [^ab] == 除了a或者b
# \d ==== [0-9] , [0123456789] \D: [^0-9] , [^0123456789]
# \w ==== [a-zA-Z_] \W:
# \s === [\n\t\r\ ] \S:
string模块
import string
# 显示所有的数字
print(string.digits)
# 显示所有的十六数字
print(string.hexdigits)
# 显示所有的八进制数字
print(string.octdigits)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/01_正则表达式.py
0123456789
0123456789abcdefABCDEF
01234567
# 显示所有字母的大小写
print(string.ascii_letters)
# 显示所有字母的小写
print(string.ascii_lowercase)
# 显示所有字母的大写
print(string.ascii_uppercase)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/01_正则表达式.py
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
2.正则表达式表示特殊子符数量个数
.*: 代表任意字符出现任意次
.: 代表任意一个字符
***** 出现次数的规则:
*: 代表*前面的字符出现0次或者无限次
+: 代表+前面的字符出现1次或者无限次
?: 代表?前面的字符出现0次或者1次;想省略的字符后面加; 1-1 \d-?\d
188-7867-8798
********出现次数(更加精确)
{m}:代表前一个字符出现m次;
{m,}: 代表前一个字符至少出现m次; >=m
{m,n}:代表前一个字符出现m次到n次之间;
练习1:
import re
s = "eriujkboytknoytnjoit188-2378-7899hcvfkjhgiuitjggtijgi188 2987 6754"
pattern = r'\d\d\d[-\s]?\d\d\d\d[-\s]?\d\d\d\d'
# [-\s] “-或空格“
或 # pattern = r'\d{3}[-\s]?\d{4}[-\s]?\d{4}'
print(re.findall(pattern,s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/01_正则表达式.py
['188-2378-7899', '188 2987 6754']
练习2:
匹配电子邮箱地址: 9761637@qq.com westos@163.com
# \w:字母、数字或下划线
# +: 1次或多次
# . 代表任意一个字符, 如果想要匹配字符'.', 一定要转义, \.
s = "hfkrejhfktrdjvnjfv westos@163.com westos123@qqd123.com jcehrfui west_os@qqd123.cn rehgtrg hello@163.com"
pattern = r'\w+@\w+\.com'
# pattern = r'\w{6,}@\w+\.com' 更准确
print(re.findall(pattern,s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/01_正则表达式.py
['westos@163.com', 'westos123@qqd123.com', 'hello@163.com']
练习3:
匹配字符串:
字符串的第一个字母大写, 后面的字母都是小写;
从/etc/httpd/conf/httpd.conf文件中找出匹配的字符串;
import re
def read_file(filename):
"""读取文件内容并返回"""
with open(filename) as f:
content = f.read()
return content
filename = '/etc/httpd/conf/httpd.conf'
fileCount = read_file(filename)
pattern = r'[A-Z][a-z]+'
print(re.findall(pattern,fileCount))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
['This', 'Apache', 'It', 'See', 'In', 'Do', 'They', 'If', 'You', 'Configuration', 'If', 'Win', 'If', 'Server', 'Root', 'Server', 'Root', 'Server', 'Root', 'The', 'Do', 'If', 'Server', 'Root', 'Mutex', 'If', 'Server', 'Root', 'Pid', 'File', 'Server', 'Root', 'Listen', 'Allows', 'Apache', 'See', 'Virtual', 'Host', 'Change', 'Listen', 'Apache', 'Listen', 'Listen', 'Dynamic', 'Shared', 'Object', 'Support', 'To', 'Load', 'Module', 'Statically', 'Example', 'Load', 'Module', 'Include', 'If', 'User', 'Group', 'The', 'It', 'User', 'Group', 'Main', 'The', 'Virtual', 'Host', 'These', 'Virtual', 'Host', 'All', 'Virtual', 'Host', 'Server', 'Admin', 'Your', 'This', 'Server', 'Admin', 'Server', 'Name', 'This', 'If', 'Server', 'Name', 'Deny', 'You', 'Directory', 'Directory', 'Allow', 'Override', 'Require', 'Directory', 'Note', 'Document', 'Root', 'The', 'By', 'Document', 'Root', 'Relax', 'Directory', 'Allow', 'Override', 'None', 'Allow', 'Require', 'Directory', 'Further', 'Directory', 'Possible', 'Options', 'None', 'All', 'Indexes', 'Includes', 'Follow', 'Sym', 'Links', 'Sym', 'Linksif', 'Owner', 'Match', 'Exec', 'Multi', 'Views', 'Note', 'Multi', 'Views', 'Options', 'All', 'The', 'Options', 'Please', 'Options', 'Indexes', 'Follow', 'Sym', 'Links', 'Allow', 'Override', 'It', 'All', 'None', 'Options', 'File', 'Info', 'Auth', 'Config', 'Limit', 'Allow', 'Override', 'None', 'Controls', 'Require', 'Directory', 'Directory', 'Index', 'Apache', 'If', 'Module', 'Directory', 'Index', 'If', 'Module', 'The', 'Web', 'Files', 'Require', 'Files', 'Error', 'Log', 'The', 'If', 'Error', 'Log', 'Virtual', 'Host', 'If', 'Virtual', 'Host', 'Error', 'Log', 'Log', 'Level', 'Control', 'Possible', 'Log', 'Level', 'If', 'Module', 'The', 'Custom', 'Log', 'Log', 'Format', 'Referer', 'User', 'Agent', 'Log', 'Format', 'If', 'Module', 'You', 'Log', 'Format', 'Referer', 'User', 'Agent', 'If', 'Module', 'The', 'Common', 'Logfile', 'Format', 'If', 'Virtual', 'Host', 'Contrariwise', 'Virtual', 'Host', 'Custom', 'Log', 'If', 'Combined', 'Logfile', 'Format', 'Custom', 'Log', 'If', 'Module', 'If', 'Module', 'Redirect', 'Allows', 'The', 'Example', 'Redirect', 'Alias', 'Maps', 'Document', 'Root', 'Example', 'Alias', 'If', 'You', 'Directory', 'Script', 'Alias', 'This', 'Script', 'Aliases', 'Aliases', 'The', 'Script', 'Alias', 'Alias', 'Script', 'Alias', 'If', 'Module', 'Script', 'Aliased', 'Directory', 'Allow', 'Override', 'None', 'Options', 'None', 'Require', 'Directory', 'If', 'Module', 'Types', 'Config', 'Types', 'Config', 'Add', 'Type', 'Types', 'Config', 'Add', 'Type', 'Add', 'Encoding', 'Note', 'Not', 'Add', 'Encoding', 'Add', 'Encoding', 'If', 'Add', 'Encoding', 'Add', 'Type', 'Add', 'Type', 'Add', 'Handler', 'These', 'Action', 'To', 'Script', 'Aliased', 'You', 'Exec', 'Options', 'Add', 'Handler', 'For', 'Add', 'Handler', 'Filters', 'To', 'You', 'Includes', 'Options', 'Add', 'Type', 'Add', 'Output', 'Filter', 'If', 'Module', 'Specify', 'To', 'Add', 'Default', 'Charset', 'If', 'Module', 'The', 'The', 'Magic', 'File', 'Magic', 'File', 'If', 'Module', 'Customizable', 'Some', 'Error', 'Document', 'The', 'Error', 'Document', 'Error', 'Document', 'Error', 'Document', 'Enable', 'Enable', 'Sendfile', 'On', 'This', 'Defaults', 'Enable', 'On', 'Enable', 'Sendfile', 'Off', 'Enable', 'Enable', 'Sendfile', 'Supplemental', 'Load', 'Include', 'Optional']
3.正则表达式表示边界
^: 以什么开头
$: 以什么结尾
import re
li = ['1882926658713', '172 2345 4232', '18823456789', '176-89020023']
pattern = r'^\d{3}[-\s]?\d{4}[-\s]?\d{4}$'
for i in li:
print(re.findall(pattern,i))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
[]
['172 2345 4232']
['18823456789']
['176-89020023']
中括号
• 中括号用于指向一个字符集合
• 中括号可以使用元字符
• 中括号中的. 表示其字面意思
[a-z] [A-Z] [0-9] [A-Za-z]
• [0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线;
• [0-9a-zA-Z\_]+ 可以匹配至少由一个数字、字母或者下划线组成的字
符串;
• [a-zA-Z\_][0-9a-zA-Z\_]{0, 19} 更精确地限制了变量的长度是 120
个字符;
•A|B 可以匹配 A 或 B
•^\d 表示必须以数字开头
• \d$ 表示必须以数字结束思考
4.正则表达式之表示分组
# |: 或者, 只需要满足|左右两边任意一个正则即可;
import re
pattern = r'root|kiosk'
with open('/etc/passwd') as f:
content = f.read()
print(re.findall(pattern,content))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
['root', 'root', 'root', 'root', 'kiosk', 'kiosk']
# (.*): findall方法时, 只会显示()里面的内容
import re
s = "westos@qq.com jukthjitojoiythji hello12@163.com"
pattern = r'\w{6,}@\w{2,}\.com'
print(re.findall(pattern,s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
['westos@qq.com', 'hello12@163.com']
s = "westos@qq.com jukthjitojoiythji hello12@163.com"
pattern = r'(\w{6,})@\w{2,}\.com'
print(re.findall(pattern,s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
['westos', 'hello12']
s = "westos@qq.com jukthjitojoiythji hello12@163.com"
pattern = r'(\w{6,})@(\w{2,})\.com'
print(re.findall(pattern,s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
[('westos', 'qq'), ('hello12', '163')] # 以列表嵌套元组的方式输出
# \num: 引用分组的第num个匹配到的字符串
import re
s = "<html><h1>这是一个标签</h1></html>"
pattern = r"<(.+)><(.+)>(.*)</\2></\1>"
print(re.findall(pattern, s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
[('html', 'h1', '这是一个标签')]
**# match方法**
import re
s = "<html><h1>这是一个标签</h1></html>"
pattern = r"<(.+)><(.+)>(.*)</\2></\1>"
reObj = re.match(pattern,s)
if reObj:
print(reObj.group())
print(reObj.groups())
print(reObj.groupdict())
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
<html><h1>这是一个标签</h1></html>
('html', 'h1', '这是一个标签')
{}
# (?P) 给分组起别名, (?P=name)引用分组的别名
import re
s = "http://www.cbrc.gov.cn/chinese/jrjg/index.html"
pattern = r'http://(?P<domainName>.+)/(?P<languages>\w+)/\w+/.+'
print(re.findall(pattern,s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
[('www.cbrc.gov.cn', 'chinese')]
import re
s = "http://www.cbrc.gov.cn/chinese/jrjg/index.html"
pattern = r'http://(?P<domainName>.+)/(?P<languages>\w+)/\w+/.+'
regObj = re.match(pattern, s)
if regObj:
print(regObj.group())
print(regObj.groups())
print(regObj.groupdict())
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/03_正则表达式.py
http://www.cbrc.gov.cn/chinese/jrjg/index.html
('www.cbrc.gov.cn', 'chinese')
{'domainName': 'www.cbrc.gov.cn', 'languages': 'chinese'}
5.正则表达式与爬虫
1.获取无反爬虫网页源代码:
from urllib import request
urlObj = request.urlopen(url='https://www.baidu.com/') # 不能用https
content = urlObj.read().decode('utf-8')
print(content)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/正则与爬虫.py
<html>
<head>
<script>
location.replace(location.href.replace("https://","http://"));
</script>
</head>
<body>
<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
## 正确格式
from urllib import request
urlObj = request.urlopen(url='http://www.baidu.com/')
content = urlObj.read().decode('utf-8')
print(content)
2.获取反爬虫的网页内容
import re
from urllib import request
def htmlContent(url):
# 1). 头信息:headers
headers = {'User-agent': 'Firefox/12.0'}
# 2). 告诉请求, 访问的代理为firefox浏览器
req = request.Request(url, headers=headers)
# 3). 打开url地址
urlObj = request.urlopen(req)
# 4). read方法读取网页内容, decode: 解码为‘utf-8’;
content = urlObj.read().decode('utf-8')
content = content.replace('\t', '')
return content
def pattern_html():
# 先打开网页
url='http://www.cbrc.gov.cn/chinese/jrjg/index.html'
content = htmlContent(url)
pattern = r'<a href="(http://.+)" target="_blank" style="color:#08619D">\s*(.*)\s*</a>'
bank_li = re.findall(pattern, content)
return bank_li
def write_to_file(filename, bank_li):
# w方法打开文件并写入
with open(filename, 'w') as f:
f.write("银行名称\tURL\n")
for url,name in bank_li:
f.write("%s\t%s\n" %(name.strip(), url))
print("写入成功!")
bank_li = pattern_html()
write_to_file('bank.txt', bank_li)
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/正则与爬虫.py
写入成功!
## 生成bank.txt文件
把bank.txt储存到数据库
6.正则表达式高级用法
# search:找到符合条件的第一个并返回
# findall:找到符合条件全部返回
# sub: 对于符和正则的内容进行替换
# split:指定多个分隔符进行分割;
search
import re
s = "阅读次数为10000, 转发次数为100"
pattern = r'\d+'
# search:找到符合条件的第一个并返回
print(re.search(pattern, s).group())
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/04_正则表达式高级用法.py
10000
sub
import re
s = "阅读次数为10000, 转发次数为100"
pattern = r'\d+'
# 将符和条件的都替换为0;
print(re.sub(pattern, '0', s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/04_正则表达式高级用法.py
阅读次数为0, 转发次数为0
# 将符和条件的都替换为原有值加1;
def addNum(regObj):
res = int(regObj.group()) + 1
return str(res)
print(re.sub(pattern, addNum, s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/04_正则表达式高级用法.py
阅读次数为10001, 转发次数为101
split
s = '12+18-78*67/45'
pattern = r'\+|-|\*|/'
print(re.split(pattern, s))
/usr/local/python3/bin/python3.6 /root/PycharmProjects/day11/04_正则表达式高级用法.py
['12', '18', '78', '67', '45']