Python学习笔记(四十)— 内置模块(9)HTMLParser
摘抄自: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 tutorial...<br>END</p>
</body>
</html>''')
# HTML 中的常用字符实体是不间断空格( )。
# 浏览器总是会截短 HTML 页面中的空格。如果您在文本中写 10 个空格,
# 在显示该页面之前,浏览器会删除它们中的 9 个。如需在页面中增加空格的数量,
# 您需要使用 字符实体。
结果:
<html> <head>
</head> <body> <!-- test html parser --> <p>
Some
<a>
html
</a>
HTML tutorial...
<br>
END
</p> </body> </html>
feed()方法可以多次调用,也就是不一定一次把整个HTML字符串都塞进去,可以一部分一部分塞进去。
特殊字符有两种,一种是英文表示的 ,一种是数字表示的Ӓ,这两种字符都可以通过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的更多相关文章
- Python学习笔记(十四)
Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...
- Python学习笔记(十)
Python学习笔记(十): 装饰器的应用 列表生成式 生成器 迭代器 模块:time,random 1. 装饰器的应用-登陆练习 login_status = False # 定义登陆状态 def ...
- Python学习笔记(十四):模块高级
以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-23 21:30 学习笔记 1,包导入是把计算机上的 ...
- Python学习笔记(十五):类基础
以Mark Lutz著的<Python学习手册>为教程,每天花1个小时左右时间学习,争取两周完成. --- 写在前面的话 2013-7-24 23:59 学习笔记 1,Python中的大多 ...
- python学习笔记之heapq内置模块
heapq内置模块位于./Anaconda3/Lib/heapq.py,提供基于堆的优先排序算法 堆的逻辑结构就是完全二叉树,并且二叉树中父节点的值小于等于该节点的所有子节点的值.这种实现可以使用 h ...
- python学习笔记-(十四)I/O多路复用 阻塞、非阻塞、同步、异步
1. 概念说明 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可 ...
- python学习笔记-(十四)进程&协程
一. 进程 1. 多进程multiprocessing multiprocessing包是Python中的多进程管理包,是一个跨平台版本的多进程模块.与threading.Thread类似,它可以利用 ...
- Python 学习笔记(十四)Python类(三)
完善类的内容 示例: #! /usr/bin/env python # coding =utf-8 #通常类名首字母大写 class Person(object): """ ...
- Python 学习笔记(十四)Python类(二)
创建简单的类 新式类和经典类(旧式类) Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,经典类被移除,不必显式的继承object 新式 ...
- python学习笔记(十四)之字典
字典:是python中唯一的映射类型,字典中每一项都是由键-值对组成的项.字典中没有索引,只有键和值.键的类型可以是整型,变量或字符串. 创建和访问字典: >>> dict1 = { ...
随机推荐
- python处理时间相关的方法(汇总)
记录python处理时间的模块:time模块.datetime模块和calendar模块. python版本:2.7 在介绍模块之前,先说下以下几点: 1.时间通常有这几种表示方式: a.时间戳:通常 ...
- 201621123037 《Java程序设计》第14周学习总结
作业14-数据库 标签(空格分隔): Java 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 使用数据库技术改造你的系统 2.1 简述如何使用数据库技术改造 ...
- (转)Elasticsearch search-guard 插件部署
我之前写了ELK+shield的部署文档,由于shield是商业收费的,很多人都推崇开源项目search-guard来做ELK的安全组件,准确来说是elasticsearch的安全组件.search- ...
- 【c】线性表
数据对象集:线性表是N(>=0)个元素构成的有序序列,a1,a2,a3.....a(N-1),aN,a(N+1) 线性表上的基本操作有: ⑴ 线性表初始化:Init_List(L)初始条件:表L ...
- redis 入手
redis是数据库,数据库肯定是处理处理数据.既然是处理数据,无非就是增删查改 redis用于操作键的命令基本上分为两大类 对任何键都可执行的: DEL 命令. EXPIRE 命令. RENAME 命 ...
- HDU 4758——Walk Through Squares——2013 ACM/ICPC Asia Regional Nanjing Online
与其说这是一次重温AC自动机+dp,倒不如说这是个坑,而且把队友给深坑了. 这个题目都没A得出来,我只觉得我以前的AC自动机的题目都白刷了——深坑啊. 题目的意思是给你两个串,每个串只含有R或者D,要 ...
- bzoj5090[lydsy11月赛]组题
裸的01分数规划,二分答案,没了. #include<cstdio> #include<algorithm> using namespace std; const int ma ...
- 【uoj#174】新年的破栈 贪心
题目描述 给你一个长度为 $n$ 的序列和一个空的双端队列,每次进行3种操作种的一种: 1.将序列中编号最小的数加入到双端队列的队尾:2.从双端队列的队尾取出一个数:3.从双端队列的队头取出一个数. ...
- 【JavaScript&jQuery】5秒跳转
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" ...
- 【JavaScript】JAVA-js中比较日期大小
业务场景:js中根据yyyy-MM-dd格式的日期进行比较来动态显示相关图标的出现与否 var DS173305 = { DS173305Grid: null, initDataGrid: funct ...