清洗HTML数据
算法思路:
·分析html文本信息
·导入正则:re.l、re.L、re.M、re.S...
·清洗HTML标签:DOCTYPE、CDATA、Script、style
·HTML标签、注释、换行等处理:re.compile
·实现正则清洗HTML数据
import re
"""
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响^和$
re.S 使.匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响\w,\W,\b,\B
re.X 该标签通过给予你更灵活的格式以便你将正则表达式写得更容易
"""
# 清洗HTML标签文本
# @param htmlstr HTML字符串
def filter_tags(htmlstr):
# 过滤DOCTYPE
htmlstr = ' '.join(htmlstr.split()) #去除多余空格
re_doctype = re.compile(r'<!DOCTYPE .*?>',re.S)
res = re_doctype.sub('',htmlstr)
# 过滤CDATA
re_cdata = re.comile('//<!CDATA\[[ >]//\]>',re.I)
res = re_cdata.sub('',res)
#Script
re_script = re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>',re.I)
res = re_script.sub('',res)
#style
re_style = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*script\s*>',re.I)
res = re_style.sub('',res) #去掉style
# 处理换行
re_br = re.compile('<br\s*?/?>')
res = re_br.sub('',res) # 将br转行为换行
# 处理HTML标签
re_h = re.compile('</?\w+[^>]*>')
res = re_h.sub('',res) # 去掉HTML
# 剔除超链接
http_link = re.compile(r'(http://.+html)')
res = http_link.sub('',res)
# HTML注释
re_comment = re.compile('<!--[^>]*-->')
res = re_comment.sub('',res)
# 处理多余的空格
blank_line = re.compile('\n+')
res = blank_line.sub('',res)
blank_line_1 = re.compile('\n+')
res = blank_line_1.sub('',res)
blank-line_kon = re.compile('\t')
res = blank_line_kon.sub('',res)
blank_line_one = re.compile('\r\n')
res = blank_line_one.sub('',res)
blank_two = re.compile('\t')
res = blank_two.sub('',res)
blank_three = re.compile('\t')
res = blank_three.sub('',res)
return
def readFile(path):
str_doc = ""
with open(path,'r',encoding='utf-8') as f:
str_doc = f.read()
return str_doc
if __name__=='__main__':
str_doc=readFile(r'./htmldome.txt')
res = filter_tags(str_doc)
print(res)
import re
# 正则对字符串的清洗
def textParse(str_doc):
# 正则过滤掉特殊符号、标点、英文、数字等
r1 = '[a-zA-Z0-9'!"#$%&'()*+,-./::;;|<=>?@.-。?☆、]^_`{|}~]+'
# 去除空格
r2 = '\s+'
str_doc = re.sub(r1,' ',str_doc)
str_doc = re.sub(r2,' ',str_doc)
# 去除换行符
str_doc = str_doc.replace('n','')
return str_doc
def readFile(path):
str_doc=""
with open(path,'r',encoding='utf-8')as f:
str_doc = f.read()
return str_doc
if __name__=='__main__':
# 1.读取文本
path = r'../dataSet/CSCMNews/体育/0.txt'
str_doc = readFile(path)
# print(str_doc)
# 2.数据清洗
mystr=textParse(str_doc)
print(mystr)以上是课堂代码
高效读取30万新闻
算法思路:
·构建生成器类算法
·构建迭代器类算法
·高效读取30万新闻
·读取30万新闻算法性能对比
import os,time
# 迭代器类
class loadFolders(object):
def __init__(self,par_path):
self.par_path = par_path
def __iter__(self):
for file in os.listdir(self.par_path):
file_abspath = os.path.join(self.par_path,file)
if os.path.isdir(file_abspath):
yield file_abspath #return
class loadFiles(object):
def __init__(self,par_path):
self.par_path = par_path
def __iter__(self):
folders = loadFolders(self.par_path)
for folder in folders:
catg = folder.split(os.sep)[-1]
for file in os.listdir(folder):
yield catg,file
if __name__=='__main__':
filepath = os.path.abspath(r'../dataSet/CSCMNews/')
files = loadFiles(filepath)
for i,msg in enumerate(files):
if i%10000==0:
print('{t}***{i} \t docs has been read'.format(i=i,t=time.strftime('%Y-%m-%d %H:%M:%S',time,localtime())))
end = time.time()
print('Total spent times:%.2f' % (end - start))
生成器小结:
·数组、链表、字符串、文件等缺点就是所有的数据都在内存里,海量的数据耗内存。
·生成器是可以迭代的,工作原理就是重复调用next()方法,直到捕获一个异常。
·有yield的函数不再是一个普通的函数,而是一个生成器generator,可用于迭代。
·yield是一个类似return的关键字。
递归读取30万新闻
算法思路:
·实现文件遍历递归算法回顾
·遍历读取30万新闻
·每万条读取打印一次屏幕
·完成30万新闻遍历读取
import os,time
"""
功能描述:遍历目录,对子文件单独处理
"""
# 2 遍历目录文件
def TraversalDir(rootDir):
#返回指定目录包含的文件或文件夹的名字的列表
for i,list in enumerate(os.listdir(rootDir)):
# 待处理文件夹名字列表
path = os.path.join(rootDir,lists)
# 核心算法,对文件具体操作
if os.path.isfile(path):
if i%10000 == 0:
print('{t}***{i} \t {f} docs has been read'.format(i=i,t=time.
strftime('%Y-%m-%d %H:%M:%S',time.localtime())))
# 递归遍历文件目录
if os.path.isdir(path):
TraversalDir(path)
if __name__=='__main__':
t1=time.time()
rootDir = r' /dataSet/CSC'
TraversalDir(rootDir)
t2 = time.time()
print('Total Cost Time %.2f' %(t2-t1)+'s')
yield生成器
算法思路:
·斐波那契数列介绍和数学描述
斐波那契数列:从数列的第三项开始,后面每一项是前面两项之和
数学上的定义:F(0)=1,F(1)=1,...。F(n)=F(n-1)(n>=2,nn∈N﹢)
·斐波那契数列算法实现
·斐波那契数列算法生成器实现
·算法时间性能对比分析
笔记
%%writefile aa.py # jupyter notebook中某个cell保存到路径中
%load aa.py #jupyter notebook中加载某个py文件内容
from aa import * 从aa.py中导入所有函数
__name__ =='__main__':这个下面的代码不在调用中执行,只在当前代码中执行
#设计matplotlib全局字体
import matplotlib
matplotlib.rc("font",family='SimHei')
#局部设置改变字体
font1 = FontProperties(fname=r"c:\windows\fonts\simsun.ttc")
font2 = FontProperties(fname=r"c:\windows\fonts\STHUPO.TTF")
font3 = FontProperties(fname=r"c:\windows\fonts\STCAIYUN.TTF")
plt.xlabel("横轴/单位",fontproperties=font1)
plt.ylabel("纵轴/单位",fontproperties=font1)
plt.title("标题",fontproperties=font3)
以前在写到读取文件的代码时,经常要用到文件的路径,而每次让我有点搞的糊涂的就是斜杠的用法,又是正斜杠又是反斜杠的,还有双斜杠的,经常要经过几次调试才能正确的把文件的路径弄对,究其原因,主要是每次都没有认真的去总结,总是只要弄出来了就算过了,这样导致每次都会在这个问题上纠结一会,今天终于查了会资料,再加上自己的一些理解,总结一下,以便是我印象更加深刻,也使有需要的同学看到可以根本的解决这个问题。
“\” 这个是反斜杠,也称左斜杠。
“/” 这个是正斜杠,也称右斜杠,斜杠。
在windows中文件的文件的路径是用反斜杠(\)表示(当初是为了和Unix的文件路径使用”/“区分开来),例如 C:\windows\system,但是我们在写程序的时候能不能再路径的字符串中写成C:\windows\system?答案是不能的,这一点想一下就会可以理解,在很多编译器中,“\”是一个转义字符,例如“\n,\r”等,如果在程序中写成“C:\windows\system“那么实际上编译出来的就是“C:windowssystem ",从而获取不到文件,但是这个路径可以写成C:\windows\system,或者也可以用正斜杠C:/windows/system,这两中方式都是可以的。说到这里,基本上这两种用法不会混淆了,只要记住”\“反斜杠有转义的功能,那么写路径的时候就不会出问题了。
顺便拓展一下,文件的相对路径和绝对路径:
例如一个绝对路径:C:\Windows\System\aaa.dll 如果当前目录是C:\windows 那么aaa.dll这个文件的地址可以表示为:
./system/aaa.dll 中”.“表示当前路径, …/windows/system/aaa.dll中”…“表示父级目录。
2.script的清洗
3.style的清洗
1.re.S
1.with open这种方式可以自己关闭不用我们自己关
1.非贪婪模式只匹配一次 s+至少出现一次
n,a,b =0,0,1 <= 这个和JavaScript里ES6的结构赋值有点像.(好像不叫解构赋值...).
好好看呢讷讷
jieba分词主要功能
jieba分词核心算法简介
jieba三种分词模式与特点
jieba分词模式、核心算法
"""
Description:正则清洗HTML数据
Author:
Prompt: code in python3 env
"""
"""
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响^(开头)和$(结尾)
re.S 匹配包含换行在内的所有字符
re.U 根据Unicode字符集解析字符,这个标志影响 \w, \W, \b, \B
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更加
"""
import re
# 处理HTML标签文本
# @param htmlstr html字符串
def filter_tags(htmlstr):
# 过滤doc_type
htmlstr = ' '.join(htmlstr.split())
re_doctype = re.compile(r'<!DOCTYPE .*?>', re.S)
res = re_doctype.sub('', htmlstr)
"""
# 过滤CDATA
re_cdata = re.compile( r'//<!CDATA\[[ >] //\] >', re.I)
res = re_cdata.sub('', res)
# Script
re_script = re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>', re.I)
res = re_script.sub('', res)
# 注释
re_script = re.compile('<!--.*?-->', 0)
res = re_script.sub('', res)
# 换行符
re_br = re.compile('<br\n*?/?>')
res = re_br.sub('\n', res)
# HTML 标签
re_lable = re.compile('</?\w[^>]*>')
res = re_lable.sub('', res)
# 转义字符
re_esc = re.compile('&.*?;')
res = re_esc.sub('', res)
# 空格处理
re_blank = re.compile('\s+') # \s包含 \t \n \r \f \v
res = re_blank.sub(' ', res)
# 超链接处理
re_http = re.compile(r'(http://.+.html)')
res = re_http.sub(' ', res)
"""
# return res
re_mate = [
(r'<!DOCTYPE .*?>', re.S),
(r'//<!CDATA\[[ >] //\] >', re.I),
(r'<\s*script[^>]*>[^<]*<\s*/\s*script\s*>', re.I),
(r'<!--.*?-->', re.I),
(r'<br\n*?/?>', ),
(r'</?\w[^>]*>', ),
(r'&.*?;', ),
(r'\s+', ),
(r'(http://.+.html)', ),
]
d = lambda pattern, flags=0: re.compile(pattern, flags)
for re_type in re_mate:
re_type = d(*re_type)
res = re_type.sub(' ', res)
return res
def read_file(read_path):
str_doc = ''
with open(read_path, 'r', encoding='utf-8') as f:
str_doc = f.read()
return str_doc
if __name__ == '__main__':
str_doc = read_file(r're.html')
res = filter_tags(str_doc)
print(res)
# with open(r'../data/html/test.html', 'w', encoding='utf-8') as f:
# f.write(res)
# print('No Exception') # 我是通过另一个编辑器进行打开预览的这是我做的笔记,和老师的有些不一样但是效果一样的
学习要点。
本节课程要点
本节课程要点