python:html元素解析
说明
主要是总结我通过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 codecs
from 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,socket
from 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
python:html元素解析的更多相关文章
- 转 web项目中的web.xml元素解析
转 web项目中的web.xml元素解析 发表于1年前(2014-11-26 15:45) 阅读(497) | 评论(0) 16人收藏此文章, 我要收藏 赞0 上海源创会5月15日与你相约[玫瑰里 ...
- python中html解析-Beautiful Soup
1. Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.pyt ...
- Python迭代和解析(1):列表解析
解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html Python中的解析 Python支持各种解析(comprehensio ...
- Python之XML解析详解
什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这 ...
- python实现XML解析的三种方法
python实现XML解析的三种方法 三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合:二是xml.sax.*模块,它是SAX API的实 ...
- python统计元素重复次数
python统计元素重复次数 # !/usr/bin/python3.4 # -*- coding: utf-8 -*- from collections import Counter arr = [ ...
- python学习(解析python官网会议安排)
在学习python的过程中,做练习,解析https://www.python.org/events/python-events/ HTML文件,输出Python官网发布的会议时间.名称和地点. 对ht ...
- python爬虫数据解析之BeautifulSoup
BeautifulSoup是一个可以从HTML或者XML文件中提取数据的python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. BeautfulSoup是python爬虫三 ...
- python命令行解析模块--argparse
python命令行解析模块--argparse 目录 简介 详解ArgumentParser方法 详解add_argument方法 参考文档: https://www.jianshu.com/p/aa ...
随机推荐
- Go-接口(作用类似python类中的多态)
一.定义接口 type Person interface { Run() //只要有run方法的都算 Person结构体 } //还有定义方法 type Person2 interface { Spe ...
- Android Gradle 学习笔记(四):Gradle 构建脚本
本节我们从整体的角度来介绍一下Gradle. 一.setting.gradle 在Gradle中,定义了一个设置文件,用于初始化以及工程树的配置.设置文件的默认的名字就是setting.gradle, ...
- Saltstack_使用指南14_无master
1. 主机规划 salt 版本 [root@salt100 ~]# salt --version salt (Oxygen) [root@salt100 ~]# salt-minion --versi ...
- php number_format金钱 价格 格式处理 由分单位转换成元(保留2为小数)
/** * priceFormat * 价格格式处理 * * @access public * @param null * @since 1.0 * @return object */ if(!fun ...
- Python虚拟环境导出包安装到另一台电脑的方法
环境:Windows 版 Python Python 3.6.8可以用自带的命令建立虚拟环境,不用安装另外的如 virtualenv.virtualenvwrapper等工具. python -m v ...
- python2 和 python3共存的常见使用(如安装虚拟环境的问题)
1.安装好python2和python3,配置好全部环境变量 环境变量修改后,需要重新启动命令行才有效 2.如何启动不同版本的python 启动的时候会执行python.exe,python2和pyt ...
- Undo 相关的等待事件和已知问题 (Doc ID 1575701.1)
Undo Related Wait Events & Known Issues (Doc ID 1575701.1) APPLIES TO: Oracle Database - Enterpr ...
- keepass可以在浏览器中使用吗?
KeePass不提供浏览器扩展,因此当您访问登录页面时,它不会弹出并提示您.您可以将登录信息从KeePass复制粘贴到网页上的相应框中,甚至可以使用拖放操作将用户名和密码移至上方,但这不是最方便的解决 ...
- MATLAB实例:构造网络连接图(Network Connection)及计算图的代数连通度(Algebraic Connectivity)
MATLAB实例:构造网络连接图(Network Connection)及计算图的代数连通度(Algebraic Connectivity) 作者:凯鲁嘎吉 - 博客园 http://www.cnbl ...
- python做中学(七)ord() 函数
描述 ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII ...