摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014320023122880232500da9dc4a4486ad00426f081c15000

如果要编写一个搜索引擎,第一步是用爬虫把目标网站的页面抓下来,第二步就是解析该HTML页面,看看里面的内容到底是新闻、图片还是视频。

假设第一步已经完成了,第二步应该如何解析HTML呢?

HTML本质上是XML的子集,但是HTML的语法没有XML那么严格,所以不能用标准的DOM或SAX来解析HTML。

Python提供了HTMLParser来非常方便地解析HTML,只需简单几行代码:

from html.parser import HTMLParser
from html.entities import name2codepoint class MyHTMLParser(HTMLParser): def handle_starttag(self, tag, attrs):
print('<%s>' % tag) def handle_endtag(self, tag):
print('</%s>' % tag) def handle_startendtag(self, tag, attrs):
print('<%s/>' % tag) def handle_data(self, data):
print(data) def handle_comment(self, data): # 解析评论
print('<!--', data, '-->') def handle_entityref(self, name): # 解析实体
print('&%s:' % name) def handle_charref(self, name):
print('&#%s:' % name) if __name__=='__main__':
parser = MyHTMLParser()
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
<p>Some <a href=\"#\">html</a> HTML&nbsp;tutorial...<br>END</p>
</body>
</html>''')
# HTML 中的常用字符实体是不间断空格(&nbsp;)。
# 浏览器总是会截短 HTML 页面中的空格。如果您在文本中写 10 个空格,
# 在显示该页面之前,浏览器会删除它们中的 9 个。如需在页面中增加空格的数量,
# 您需要使用 &nbsp; 字符实体。

结果:

<html>

<head>
</head> <body> <!-- test html parser --> <p>
Some
<a>
html
</a>
HTML tutorial...
<br>
END
</p> </body> </html>

feed()方法可以多次调用,也就是不一定一次把整个HTML字符串都塞进去,可以一部分一部分塞进去。

特殊字符有两种,一种是英文表示的&nbsp;,一种是数字表示的Ӓ,这两种字符都可以通过Parser解析出来。

小结

利用HTMLParser,可以把网页中的文本、图像等解析出来。

练习

找一个网页,例如https://www.python.org/events/python-events/,用浏览器查看源码并复制,然后尝试解析一下HTML,输出Python官网发布的会议时间、名称和地点。

# -*- coding: utf-8 -*-
# 建议1: 子类在重载构造函数时不要忘了调用父类的构造函数
# 建议2: HTMLParser的attrs是一个元素为tuple的list
# 建议3: 调用类属性时,一定要加self, 否则相当于声明了新的临时变量 from html.parser import HTMLParser
from html.entities import name2codepoint
from urllib import request class MyHTMLParser(HTMLParser): # 解析一下HTML,输出Python官网发布的会议时间、名称和地点。
def __init__(self):
super().__init__()
self._event_title = []
self._event_location = []
self._event_time = []
self._reading_title = False
self._reading_time = False
self._reading_location = False # 解析头标签
def handle_starttag(self, tag, attrs):
if tag == 'time':
self._reading_time = True
if len(attrs) >= 1:
if tag == 'h3' and attrs[0][1] == 'event-title':
self._reading_title = True
if tag == 'span' and attrs[0][1] == 'event-location':
self._reading_location = True # 解析内容
def handle_data(self, data):
if self._reading_title:
self._event_title.append(data)
self._reading_title = False
if self._reading_time:
self._event_time.append(data)
self._reading_time = False
if self._reading_location:
self._event_location.append(data)
self._reading_location = False @property
def data(self):
self._data = []
for i in range(len(self._event_title)):
dic = {}
dic["title"] = self._event_title[i]
dic["time"] = self._event_time[i]
dic["location"] = self._event_location[i]
self._data.append(dic)
return self._data def getHtml():
with request.urlopen('https://www.python.org/events/python-events/') as f:
data = f.read().decode('utf-8')
return data parser = MyHTMLParser()
parser.feed(getHtml())
for item in parser.data:
print(str(item))

结果:

{'time': '07 Sept. – 11 Sept. ', 'location': 'Waseda University, Nishi-Waseda Campus, Building 63, Tokyo, Japan', 'title': 'PyCon JP 2017'}
{'time': '08 Sept. – 11 Sept. ', 'location': 'Universidade de Caxias do Sul (UCS), Caxias do Sul, Rio Grande do Sul, Brazil', 'title': 'Python Sul'}
{'time': '15 Sept. – 17 Sept. ', 'location': 'Lagos, Nigeria', 'title': 'PyCon Nigeria 2017'}
{'time': '21 Sept. – 25 Sept. ', 'location': 'Toulouse, France', 'title': 'PyCon FR 2017'}
{'time': '22 Sept. – 25 Sept. ', 'location': 'Caceres, Spain', 'title': 'PyConES17'}
{'time': '28 Sept. – 30 Sept. ', 'location': 'United States International University, Nairobi, Kenya', 'title': 'PyConKE 2017'}
{'time': '28 Aug. – 02 Sept. ', 'location': 'Erlangen, Germany', 'title': 'EuroSciPy 2017'}
{'time': '26 Aug. – 28 Aug. ', 'location': 'Kuala Lumpur, Malaysia', 'title': 'PyCon APAC 2017'}

Python学习笔记(四十)— 内置模块(9)HTMLParser的更多相关文章

  1. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  2. Python学习笔记(十)

    Python学习笔记(十): 装饰器的应用 列表生成式 生成器 迭代器 模块:time,random 1. 装饰器的应用-登陆练习 login_status = False # 定义登陆状态 def ...

  3. Python学习笔记(十四):模块高级

    以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-23 21:30 学习笔记 1,包导入是把计算机上的 ...

  4. Python学习笔记(十五):类基础

    以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-24 23:59 学习笔记 1,Python中的大多 ...

  5. python学习笔记之heapq内置模块

    heapq内置模块位于./Anaconda3/Lib/heapq.py,提供基于堆的优先排序算法 堆的逻辑结构就是完全二叉树,并且二叉树中父节点的值小于等于该节点的所有子节点的值.这种实现可以使用 h ...

  6. python学习笔记-(十四)I/O多路复用 阻塞、非阻塞、同步、异步

    1. 概念说明 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可 ...

  7. python学习笔记-(十四)进程&协程

    一. 进程 1. 多进程multiprocessing multiprocessing包是Python中的多进程管理包,是一个跨平台版本的多进程模块.与threading.Thread类似,它可以利用 ...

  8. Python 学习笔记(十四)Python类(三)

    完善类的内容 示例: #! /usr/bin/env python # coding =utf-8 #通常类名首字母大写 class Person(object): """ ...

  9. Python 学习笔记(十四)Python类(二)

    创建简单的类 新式类和经典类(旧式类) Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,经典类被移除,不必显式的继承object 新式 ...

  10. python学习笔记(十四)之字典

    字典:是python中唯一的映射类型,字典中每一项都是由键-值对组成的项.字典中没有索引,只有键和值.键的类型可以是整型,变量或字符串. 创建和访问字典: >>> dict1 = { ...

随机推荐

  1. tomcat开发环境配置

    1.环境配置教程 环境变量.安装版.配置版 2.编写启动tomcat的批处理文件 3.改变端口 4.虚拟目录

  2. Improving the Safety, Scalability, and Efficiency of Network Function State Transfers

    Improving the Safety, Scalability, and Efficiency of Network Function State Transfers 来源:ACM SIGCOMM ...

  3. 青岛 2016ICPC 区域现场赛题目

    A. Relic Discovery B. Pocket Cube C. Pocky D. Lucky Coins E. Fibonacci F. Lambda Calculus G. Coding ...

  4. PXE Centos7和Centos6

    外网网卡:192.168.23.10, 内网网卡:192.168.10.2 PXE(preboot execute environment,预引导执行环境)是由Intel公司开发的最新技术,工作于Cl ...

  5. vue-cli脚手架搭建

    我们使用vue-cli来搭建整个项目,vue-cli就是一个脚手架,步骤很简单,输入几个命令之后就会生成整个项目,里面包括了webpack.ESLint.babel很多配置等等,省了很多事 Vue+ ...

  6. QQueue与QStack使用

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QQueue与QStack使用     本文地址:http://techieliang.com ...

  7. Struts按着配置文件的加载的顺序,后面文件和前面文件相同的配置,后面的会把前面的文件的值覆盖

    Struts按着配置文件的加载的顺序,后面文件和前面文件相同的配置,后面的会把前面的文件的值覆盖

  8. Importing/Indexing database (MySQL or SQL Server) in Solr using Data Import Handler--转载

    原文地址:https://gist.github.com/maxivak/3e3ee1fca32f3949f052 Install Solr download and install Solr fro ...

  9. bzoj2386 [CEOI2011] Team

    题意 给你n个数,每个数的大小在1到n之间,要求把它们分成几组,每个数字的大小要小于等于它所在组中的数字总个数,问最多能分出多少组. 分析 首先把所有数字排序,比较显然的是最后一定存在一个最优解是按这 ...

  10. C++解析(2):进化后的 const 分析

    0.目录 1.C语言中的const 2.C++中的const 3.对比 3.1 C语言与C++中的const 3.2 C++中的const与宏定义 4.小结 1.C语言中的const const修饰的 ...