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 ...
随机推荐
- Java生鲜电商平台-电商数据运营统计与分析
Java生鲜电商平台-电商数据运营统计与分析 今天分享将会分为以下几个方面来阐述: 1. 作为运营我们需要统计与分析的几个核心数据是什么? 2. 核心数据对业务的指导价值在哪里呢? 3. 作为产品PM ...
- Ext.ux.UploadDialog上传大文件 HTTP 错误 413.1 - Request Entity Too Large Web 服务器拒绝为请求提供服务,因为该请求实体过大。Web 服务器无法为请求提供服务,因为它正尝试与客户证书进行协商,但请求实体过大。
问题描述 问题:HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求. 原因:Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值(I ...
- SVN 回滚提交的代码
有的时候,代码提交错了,我们可以通过SVN回滚到指定的版本,然后在提交回滚后的代码,即为撤销提交. 回滚代码 重新提交刚才回滚后的代码
- Implement Custom Business Classes and Reference Properties实现自定义业务类和引用属性(EF)
In this lesson, you will learn how to implement business classes from scratch. For this purpose, the ...
- JS基础语法----Math对象
推荐查看MDN----在线的帮助文档 实例对象: 通过构造函数创建出来,实例化的对象 静态对象: 不需要创建,直接就是一个对象,方法(静态方法)直接通过这个对象名字调用 实例方法必须通过实例对 ...
- javaweb 复习随笔
js和jsp区分: js是一种脚本语言,常运行在前台和客户端交互,不会给服务器带来负担,可以更好的修饰静态页面 jsp可以说是servlet的一种,jsp会先翻译,翻译成Servlet执行,运行在服务 ...
- ansible 流程控制
ansible 流程控制 使用when判断主机名 - hosts: rsync_server tasks: - name: Install rsyncd Server yum: name: rsync ...
- oracle常用查询sql
oracle常用查询sql 原创 gordon陈 发布于2018-05-10 22:32:18 阅读数 297 收藏 展开 #!/bin/sh## create by Gordon Chen echo ...
- MYSQL的备份与恢复--物理备份xrabackup
目录 1.数据库完整备份与恢复 (1)环境准备 (2)完全备份恢复流程 2.数据库增量备份与恢复 (1)增量和差异概述 (2)增量备份和恢复 3.数据库差异备份与恢复 4.简单命令进行物理备份 5.实 ...
- Day3 - Python基础3 函数基本、递归函数、内置函数
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 2.2. 函数变量作用域 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 1. 函数基本语法及 ...