基于xpath选择器、PyQuery、正则表达式的格式清理工具详解
1,使用xpath清理不必要的标签元素,以及无内容标签
fromlxmlimportetree
defxpath_clean(self,text:str,xpath_dict:dict)->str:
'''
xpath清除不必要的元素
:paramtext:html_content
:paramxpath_dict:清除目标xpath
:return:stringtypehtml_content
'''
remove_by_xpath=xpath_dictifxpath_dictelsedict()
#必然清除的项目除非极端情况一般这些都是要清除的
remove_by_xpath.update({
'_remove_2':'//iframe',
'_remove_4':'//button',
'_remove_5':'//form',
'_remove_6':'//input',
'_remove_7':'//select',
'_remove_8':'//option',
'_remove_9':'//textarea',
'_remove_10':'//figure',
'_remove_11':'//figcaption',
'_remove_12':'//frame',
'_remove_13':'//video',
'_remove_14':'//script',
'_remove_15':'//style'
})
parser=etree.HTMLParser(remove_blank_text=True,remove_comments=True)
selector=etree.HTML(text,parser=parser)
#常规删除操作,不需要的标签删除
forxpathinremove_by_xpath.values():
forbadinselector.xpath(xpath):
bad_string=etree.tostring(bad,encoding='utf-8',
pretty_print=True).decode()
logger.debug(f"cleanarticlecontent:{bad_string}")
bad.getparent().remove(bad)
skip_tip="name()='img'orname()='tr'or"\
"name()='th'orname()='tbody'or"\
"name()='thead'orname()='table'"
#判断所有p标签,是否有内容存在,没有的直接删除
forpinselector.xpath(f"//*[not({skip_tip})]"):
#跳过逻辑
ifp.xpath(f".//*[{skip_tip}]")or\
bool(re.sub('\s','',p.xpath('string(.)'))):
continue
bad_p=etree.tostring(p,encoding='utf-8',
pretty_print=True).decode()
logger.debug(f"cleanptag:{bad_p}")
p.getparent().remove(p)
returnetree.tostring(selector,encoding='utf-8',
pretty_print=True).decode()
2,使用pyquery清理标签属性,并返回处理后源码和纯净文本
#!/usr/bin/envpython
#-*-coding:utf-8-*-
frompyqueryimportPyQueryaspq
defpyquery_clean(self,text,url,pq_dict)->object:
'''
pyquery做出必要的处理,
:paramtext:
:paramurl:
:parampq_dict:
:return:
'''
#删除pq表达式字典
remove_by_pq=pq_dictifpq_dictelsedict()
#标签属性白名单
attr_white_list=['rowspan','colspan']
#图片链接key
img_key_list=['src','data-echo','data-src','data-original']
#生成pyquery对象
dom=pq(text)
#删除无用标签
forbad_taginremove_by_pq.values():
forbadindom(bad_tag):
bad_string=pq(bad).html()
logger.debug(f"cleanarticlecontent:{bad_string}")
dom.remove(bad_tag)
#标签各个属性处理
fortagindom('*'):
forkey,valueintag.attrib.items():
#跳过逻辑,保留表格的rowspan和colspan属性
ifkeyinattr_white_list:
continue
#处理图片链接,不完整url,补充完整后替换
ifkeyinimg_key_list:
img_url=self.absolute_url(url,value)
pq(tag).remove_attr(key)
pq(tag).attr('src',img_url)
pq(tag).attr('alt','')
#img标签的alt属性保留为空
elifkey=='alt':
pq(tag).attr(key,'')
#其余所有属性做删除操作
else:
pq(tag).remove_attr(key)
returndom.text(),dom.html()
3,正则表达清理空格以及换行符内容
#!/usr/bin/envpython
#-*-coding:utf-8-*-
importre
defregular_clean(self,str1:str,str2:str):
'''
正则表达式处理数据格式
:paramstr1:content
:paramstr2:html_content
:return:返回处理后的结果
'''
defnew_line(text):
text=re.sub('
','
',text)
text=re.sub(
'?a>|?em>|?html>|?body>|'
'?head>|<[a-zA-Z]{1,10}\s?/>|'
'?strong>|?blockquote>|?b>|'
'?span>|?i>|?hr>|?font>',
'',
text)
text=re.sub('\n','',text)
text=re.sub('','',text)
text=re.sub('
','',text)
text=text.replace('','\n').replace('
','
')
returntext
str1,str2=self.clean_blank(str1),self.clean_blank(str2)#TODO处理空白行问题
#TODOhtml_content处理1,删除多余的无法使用的标签以及影响数据展示的标签2,换行符问题处理以及更换
str2=new_line(text=str2)
returnstr1,str2
结尾部分,各个方法封装类代码展示
#!/usr/bin/envpython
#-*-coding:utf-8-*-
'''
author:szhan
date:2020-08-17
summery:清理html_conent以及获取纯净数据格式
'''
importre
fromlxmlimportetree
frompyqueryimportPyQueryaspq
fromurllib.parseimporturlsplit,urljoin
fromloguruimportlogger
classCleanArticle:
def__init__(
self,
text:str,
url:str='',
xpath_dict:dict=None,
pq_dict:dict=None
):
self.text=text
self.url=url
self.xpath_dict=xpath_dictordict()
self.pq_dict=pq_dictordict()
@staticmethod
defabsolute_url(baseurl:str,url:str)->str:
'''
补充url
:parambaseurl:schemeurl
:paramurl:targeturl
:return:completeurl
'''
target_url=urlifurlsplit(url).schemeelseurljoin(baseurl,url)
returntarget_url
@staticmethod
defclean_blank(text):
'''
空白处理
:paramtext:
:return:
'''
text=text.replace('
','').replace('\u3000','').replace('\t','').replace('\xa0','')
text=re.sub('\s{2,}','',text)
text=re.sub('\n{2,}','\n',text)
text=text.strip('\n').strip()
returntext
defrun(self):
'''
:return:处理后的content,html_content
'''
if(notbool(self.text))or(notisinstance(self.text,str)):
raiseValueError('html_contenthasabadtypevalue')
#首先,使用xpath去除空格,以及注释,iframe,button,form,script,style,video等标签
text=self.xpath_clean(self.text,self.xpath_dict)
#第二步,使用pyquery处理具体细节方面
str1,str2=self.pyquery_clean(text,self.url,self.pq_dict)
#最终的正则处理
content,html_content=self.regular_clean(str1,str2)
returncontent,html_content
defxpath_clean(self,text:str,xpath_dict:dict)->str:
'''
xpath清除不必要的元素
:paramtext:html_content
:paramxpath_dict:清除目标xpath
:return:stringtypehtml_content
'''
remove_by_xpath=xpath_dictifxpath_dictelsedict()
#必然清除的项目除非极端情况一般这些都是要清除的
remove_by_xpath.update({
'_remove_2':'//iframe',
'_remove_4':'//button',
'_remove_5':'//form',
'_remove_6':'//input',
'_remove_7':'//select',
'_remove_8':'//option',
'_remove_9':'//textarea',
'_remove_10':'//figure',
'_remove_11':'//figcaption',
'_remove_12':'//frame',
'_remove_13':'//video',
'_remove_14':'//script',
'_remove_15':'//style'
})
parser=etree.HTMLParser(remove_blank_text=True,remove_comments=True)
selector=etree.HTML(text,parser=parser)
#常规删除操作,不需要的标签删除
forxpathinremove_by_xpath.values():
forbadinselector.xpath(xpath):
bad_string=etree.tostring(bad,encoding='utf-8',
pretty_print=True).decode()
logger.debug(f"cleanarticlecontent:{bad_string}")
bad.getparent().remove(bad)
skip_tip="name()='img'orname()='tr'or"\
"name()='th'orname()='tbody'or"\
"name()='thead'orname()='table'"
#判断所有p标签,是否有内容存在,没有的直接删除
forpinselector.xpath(f"//*[not({skip_tip})]"):
#跳过逻辑
ifp.xpath(f".//*[{skip_tip}]")or\
bool(re.sub('\s','',p.xpath('string(.)'))):
continue
bad_p=etree.tostring(p,encoding='utf-8',
pretty_print=True).decode()
logger.debug(f"cleanptag:{bad_p}")
p.getparent().remove(p)
returnetree.tostring(selector,encoding='utf-8',
pretty_print=True).decode()
defpyquery_clean(self,text,url,pq_dict)->object:
'''
pyquery做出必要的处理,
:paramtext:
:paramurl:
:parampq_dict:
:return:
'''
#删除pq表达式字典
remove_by_pq=pq_dictifpq_dictelsedict()
#标签属性白名单
attr_white_list=['rowspan','colspan']
#图片链接key
img_key_list=['src','data-echo','data-src','data-original']
#生成pyquery对象
dom=pq(text)
#删除无用标签
forbad_taginremove_by_pq.values():
forbadindom(bad_tag):
bad_string=pq(bad).html()
logger.debug(f"cleanarticlecontent:{bad_string}")
dom.remove(bad_tag)
#标签各个属性处理
fortagindom('*'):
forkey,valueintag.attrib.items():
#跳过逻辑,保留表格的rowspan和colspan属性
ifkeyinattr_white_list:
continue
#处理图片链接,不完整url,补充完整后替换
ifkeyinimg_key_list:
img_url=self.absolute_url(url,value)
pq(tag).remove_attr(key)
pq(tag).attr('src',img_url)
pq(tag).attr('alt','')
#img标签的alt属性保留为空
elifkey=='alt':
pq(tag).attr(key,'')
#其余所有属性做删除操作
else:
pq(tag).remove_attr(key)
returndom.text(),dom.html()
defregular_clean(self,str1:str,str2:str):
'''
正则表达式处理数据格式
:paramstr1:content
:paramstr2:html_content
:return:返回处理后的结果
'''
defnew_line(text):
text=re.sub('
','
',text)
text=re.sub(
'?a>|?em>|?html>|?body>|'
'?head>|<[a-zA-Z]{1,10}\s?/>|'
'?strong>|?blockquote>|?b>|'
'?span>|?i>|?hr>|?font>',
'',
text)
text=re.sub('\n','',text)
text=re.sub('','',text)
text=re.sub('
','',text)
text=text.replace('','\n').replace('
','
')
returntext
str1,str2=self.clean_blank(str1),self.clean_blank(str2)#TODO处理空白行问题
#TODOhtml_content处理1,删除多余的无法使用的标签以及影响数据展示的标签2,换行符问题处理以及更换
str2=new_line(text=str2)
returnstr1,str2
if__name__=='__main__':
withopen('html_content.html','r',encoding='utf-8')asf:
lines=f.readlines()
html=''
forlineinlines:
html+=line
ca=CleanArticle(text=html)
_,html_content=ca.run()
print(html_content)
总结
到此这篇关于基于xpath选择器、PyQuery、正则表达式的格式清理工具详解的文章就介绍到这了,更多相关PyQuery、正则表达式的格式清理工具内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。