模块(四)
subprocess模块
sub:子
process:进程
可以通过python给操作系统发送终端命令,并且得到返回值
import subprocess
popen(cmd命令,shell=True,stdout=subprocess.PIPE,stder=subprocess.PIPE)
调用popen就会将用户的终端命令发送给本地操作系统是终端,得到一个对象,包含着正确或错误的结果
re模块
认识re
正则表达式:
正则表达式是一门独立的技术,任何语言都可以使用正则表达式.
正则表达式是由一堆特殊的字符串组合而来的.
—字符串,元字符组合使用
re模块:
在python中,若想使用正则表达式,必须通过re模块来实现.
使用re
比如获取’一堆字符串’的’某些字符’,正则表达式可以帮我们过滤,并且去除想要的字符数据
例如:
获取'redwei'
'asdfgfdfsagffff redwei asdfadfdsa'
应用场景:
爬虫:re,beautifusoup4,xpath,selector
数据过滤分析:re,pands,numpy
用户名与密码手机号检测输入内容的合法性
检测手机号:
phone_number.startswith('以--开头的号码')
re校验:
^:代表'开头'
$:代表'结束'
|:代表'或'
(12|13):可以获取一个值,判断是否是12或13
[]:分组限制取值范围
[0-9]:限制只能获取0-9的某一个字符(注意:字符组只能按照ascll码表顺序)
元字符
组合使用:
wW:匹配字母数字下划线与非字母下划线,匹配到所有.
dD:无论是数字或者非数字都可以匹配
:table
:换行
:匹配到单词结尾,tank jsonk
^:startswith
-
‘^’:在外面使用
$:endswith
^$:配合使用叫做精准匹配,如何限制一个字符串的长度或者内容
|:或。ad|abc如果第一个条件成立,则abc不会执行,怎么解决,针对这种情况把长的写在前面就好了,一定要将长的放前面。
详细看下表(或百度更多方法):
re模块的三种比较重要的方法:
findall():-----[]
-
可以匹配’所有字符’,拿到返回的结果,返回的结果是一个列表.
-
'adsadfsasfa'#a ['a','a','a','a']
search(): —>obj --> obj.group()
-
'asdfasfsasfa'#a 在匹配到一个字符后,拿到结果返回结束,不往后匹配 'a'
math(): -->obj–>obj.group()
-
'asdadfadsda'#a 'a' 'wdadsadadds'#a 'none' 从匹配字符的开头匹配,若开头不是想要的内容,则返回none.
爬虫
爬虫四部原理:
- 发送请求:requrstes
- 获取响应数据:对方机器直接返回的
- 解析并且提取想要的数据:re
- 保存提取后的数据:with open()
爬虫三部曲:
- 发送请求
- 解析数据
- 保存数据
1.发送请求:
def get_page(url):
response = requests.get(url)
#response.content 获取二进制流数据,比如图片视频音频
#response.test 获取相应文本,比如html代码
return response
2.解析数据:
#response = get_page('url地址')
#parser_page(response.text)
def parser_page(text): #response.text
#re.findall('正则表达式','过滤文本)
res_list = re.findall(
'<div class="item">.*?<a href="(.*?)">.*?<span class="title">(.*?)</span>.*?<span class="rating_num".*?>(.*?)</span>.*?<span>(.*?)人评价',text,re.S)
for movie_tuple in res_list:
#print(movie_tuple)
yield movie_tuple
3.保存数据:
#res_list = parser_page(text)
#save_data(res_list)
def save_data(res_list_iter):
with open('douban.txt','a',encoding='utf8') as f:
for movie_tuple in res_lsit_iter:
movie_url, movie_name,movie_point,movie_num=movie_tuple
#写入文件前的模样
str = f'''电影地址: {movie_url}
电影名字: {movie_name}
电影评分: {movie_point}
评价人数: {movie_num}
'''
f.write(strl)
logging模块
logging是用来记录日志的模块,一般记录用户在软件的操作.
LOGGING_DICT={}配置
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
}
def get_logger(user_type):
#加载log配置字典到logging模块的配置中
logging.condig.dictConfig(LOGGING_DIG)
#获取日志文件对象
logger = logging.getLogger(user_type)
return logger
logger = get_logger('user')
logger.info('日志消息')
–name–
–name–属于模块名称空间中的一个名字,导入模块时就会产生
防止导入模块时自动执行测试功能
if --name--=='--main--':
执行测试模块
包
import 包.模块名(包.模块.名字)
form 包 import 模块名
from 包 模块 import 模块中的名字
导入包时发生的事情:
- 当包被导入时,会以包中的–init–.py来产生一个名称空间.
- 然后执行–init–.py文件,会将–init–.py中的所有名字添加到名称空间中.
- 接着会将包下所有的模块的名字加载到–init–.py产生的名称空间中
- 导入的模块指向的名称空间其实就是–init–.py产生的名称空间中.