python:html元素解析
来源:互联网 发布:软件项目汇报 模板 编辑:程序博客网 时间:2024/06/11 22:24
说明
主要是总结我通过python实现html解析的一个初步的思路和记录实现基础html解析的代码。本解析方式仅仅
只是实现了html按元素解析的功能,具体元素的分类获取还得需要再进行进一步的优化。
html解析
html解析,当前实现我将其分为两个部分:一个是元素节点的定义,一个是元素节点解析。
1) 解析实现
解析通过html的节点进行控制,通过遍历html中的所有节点,对节点进行数据描述。html中的节点(即元素)
格式为:
<element ..../> #单闭合<element ...>....</element> #节点闭合
目前支持这两类节点的解析(对于不规范的节点书写解析当前或存在一些问题),通过对节点的数据的定义(节点
名称,节点状态(start,end),节点包含文本,节点包含属性等),python实现通过定义类对象对元素进行定
义。代码如下:
class Element: elementName="Doucument" START_DOCUMENT = 0 START_HTML = 1 START_HEAD = 2 END_HEAD = 3 START_BODY =4 END_BODY=5 START_ELEMENT=6 END_ELEMENT=7 ELEMENT_TEXT=8 END_HTML=9 END_DOCUMENT=10 NO_ELEMENT=100 ''' html基本元素 elementName:元素名称(header,body之类) text:元素包含文本内容 ''' def __init__(self,elementName=None,text=None,id=None,**attributes): if elementName: self.elementName=elementName if text: self.text=text if id: self.id=id if attributes and len(attributes)>0: self.attributes=attributes self.content=None self.elementDict={} def getElementId(self): return self.id def toString(self): if self.content: return self.content else: buffer="" if self.attributes and len(self.attributes): for key in self.attributes: if len(buffer): buffer = "%s=\"%s\"" % (key[0],key[1]) else: a=buffer buffer="%s %s=\"%s\"" %(a,key[0],key[1]) if self.text and len(self.text): return "<%s %s> %s </%s>" %(self.elementName,buffer,self.text,self.elementName) else: return "<%s %s/>" % (self.elementName,buffer) @staticmethod def element(content=None): # print "content:%s" % content element = Element() if content and len(content.strip().rstrip())>0: eleStr=content.strip().rstrip() element.content=content if len(eleStr) and not eleStr.startswith("<"): ''' text 内容 ''' element.elementName=Element.elementName element.text=eleStr element.id=Element.ELEMENT_TEXT elif len(eleStr) and eleStr.startswith("<"): ''' 标签内容 ''' if eleStr.startswith('</'): ''' element 结束符号 ''' element.id=Element.END_ELEMENT element.elementName=eleStr[2:len(eleStr)-1] if element.elementName: if hasattr(element,"END_"+element.elementName.upper()): element.id=getattr(element,"END_"+element.elementName.upper()) else: element.id=Element.END_ELEMENT else: ''' element 开始符号 ''' element.id=Element.START_ELEMENT params_str=None if eleStr.endswith("/>"): params_str=eleStr[1:-2] else: params_str=eleStr[1:-1] if not params_str: assert "Unpredictable error." params=params_str.split() element.elementName=params[0] attr_dict = {} prev_key=None for attr in params[1:]: if "=" in attr: attr_map=attr.split("=") key=attr_map[0].strip().rstrip() value_str=attr_map[1].strip().rstrip() index=len(value_str) value=value_str[1:index-1] attr_dict[key]=value prev_key=key else: if attr.endswith("\""): attr_dict[prev_key]+=" "+attr[:-1] else: attr_dict[prev_key] += " " + attr if len(attr_dict) >0: element.attributes=attr_dict if hasattr(element,"START_"+element.elementName.upper()): element.id = getattr(element, "START_" + element.elementName.upper()) else: element.id=Element.START_ELEMENT Element.elementName=element.elementName else: element.elementName=None element.text=None element.attributes=None element.id=Element.NO_ELEMENT return element
2) 解析实现
html解析通过标志”<”和”>”实现对html元素的解析,解析实现通过生成器的方式,逐个迭代。解析主要分为
三个类型:
简单的单个元素集合
单一开始和结束元素集合,格式如下:
<html> #单一开始</html> #单一结束
单封闭(自封闭)元素集合
自封闭的元素单独处理,会自动迭代成开始标签和结束标签,格式如下:
<input type="submit" value="Submit" /> #自封闭
元素文本数据
元素文本单独处理,是处于元素开始和结束标签之间的文本数据,依赖文本之前的开始标签
如上,为基本的格式介绍,python解析代码如下所示:
import codecsfrom params import *class Parser: ''' html parser class. ''' def __init__(self,fileName=None): self.fileName=fileName self.begin=0 self.over=0 self.index=0 def parser(self): if not self.fileName: raise "File not found." with codecs.open(filename=self.fileName, mode='r', encoding='utf-8') as inputfile: content = inputfile.read() if (not content) or len(content.strip().rstrip())==0: raise "get file content false." content=unicode(content.strip().rstrip()) # print "total content:", content try: index=content.index("<html") if ("<html" in content) else content.index("<html") except BaseException as error: print "parse erro:",str(error) assert True content=content[index:] # print "get content:",content #----------------------------------begin parser------------------------- yield Element.element("<DOCUMENT>") while True: try: self.begin= content.index("<",self.over) #element begin index. if self.begin> self.over: text=content[self.over+1:self.begin].strip().rstrip() if text and len(text)>0: yield Element.element(text) self.over= content.index(">",self.begin) #element end index elementStr=content[self.begin:self.over+1].rstrip().strip() # print "elementStr:",elementStr if elementStr and len(elementStr): if elementStr.startswith("<!"): pass elif elementStr.endswith("/>"): yield Element.element(elementStr[:-2]+">") yield Element.element("</"+elementStr.split()[0][1:]+">") else: yield Element.element(elementStr) except BaseException as error: print "index error:",str(error) break #-------------------------------end parser---------------------------------- yield Element.element("</DOCUMENT>")
3) 使用
完成如上的解析操作,使用就简单很多,直接通过for循环遍历,具体操作需要自行解析,代码如下:
import codecs,sys,socketfrom parser import *fileName = "test.html"content = ""parser=Parser(fileName)a=parser.parser()for b in a: if b.elementName == 'img': print "img url is:", b.attributes['src']
如上,即是一个简易版的html解析实现,
示例代码在:https://github.com/fishly/graphicsProject-/tree/master/robots/htmlpraser
Enjoytoday,EnjoyCoding
- python:html元素解析
- python模块学习---HTMLParser(解析HTML文档元素)
- python模块学习---HTMLParser(解析HTML文档元素)
- python模块学习---HTMLParser(解析HTML文档元素)
- Python lxml解析HTML并用xpath获取元素
- 解析 HTML DocumentType 元素
- HTML页面元素解析
- 深入解析 HTML DocumentType 元素
- 用python解析html
- 用python解析html
- 用python解析html
- python解析html/xml
- python HTML解析器
- python html解析
- python 解析html
- python 解析HTML
- Python 抓取解析HTML
- Python+lxml解析html
- C语言strerror错误代码与其对应内容
- 理解单例模式
- 云服务器 ECS CentOS 7配置默认防火墙 Firewall
- PHP接口开发签名验证原理详解
- AtCoder-2362 (dfs+优化)
- python:html元素解析
- (36)RuntimeException和创建自定义的RuntimeException子异常类和一些例子
- POJ 2229 Sumsets
- git忽略已跟踪的文件状态
- Python3.x与Python2.x关于sorted函数用法比较
- centos6.5安装MATLAB
- RabbitMQ消息分发模式----"Topic"主题模式
- jsoup介绍
- 底层驱动更改camera预览大小(rk)