第020课:⽤Python解析HTML⻚⾯

        在上⼀课中我们讲到了使⽤Python 获取⽹络资源,如果我们获取到⼀个或多个⻚⾯,需要从⻚⾯中提取出指定的信息,⾸先得掌握解析HTML ⻚⾯的技术。上⼀课中我们把整个 HTML ⻚⾯当成⼀个字符串,使⽤正则表达式的捕获组提取出了需要的内容。但是,写出⼀个正确的正则表达式经常也是⼀件让⼈头疼的事情。为此,我们可以先了解HTML ⻚⾯的结构,在此基础上就可以掌握其他的解析 HTML ⻚⾯的⽅法。
HTML ⻚⾯的结构
        我们在浏览器中打开任意⼀个⽹站,然后通过⿏标右键菜单,选择“ 显示⽹⻚源代码 菜单项,就可以看到⽹⻚对应的HTML 代码。
        代码的第1 ⾏是⽂档类型声明,第 2 ⾏的 <html> 标签是整个⻚⾯根标签的开始标签,最后⼀⾏是根标签的结束标签 </html> <html> 标签下⾯有两个⼦标签 <head> <body> ,放在 <body> 标签下的内容会显示在浏览器窗⼝中,这部分内容是⽹⻚的主体;放在 <head> 标签下的内容不会显示在浏览器窗⼝中,但是却包含了⻚⾯重要的元信息,通常称之为⽹⻚的头部。HTML ⻚⾯⼤致的代码结构如下所示。

 

<!doctype html>
<html>
 <head>
 <!-- ⻚⾯的元信息,如字符编码、标题、关键字、媒体查询等 -->
 </head>
 <body>
 <!-- ⻚⾯的主体,显示在浏览器窗⼝中的内容 -->
 </body>
</html>
标签、层叠样式表( CSS )、 JavaScript 是构成 HTML ⻚⾯的三要素,其中标签⽤来承载⻚⾯要显示的内容,CSS 负责对⻚⾯的渲染,⽽ JavaScript ⽤来控制⻚⾯的交互式⾏为。对 HTML ⻚⾯的解析可以使⽤⼀种名为XPath 的语法,根据 HTML 标签的层次结构提取标签中的内容或标签属性;除此之外,也可以使⽤CSS 选择器来定位⻚⾯元素,如果不清楚什么是 CSS 选择器,可以移步到我的 Web 前端概述》 ⼀⽂进⾏了解。
XPath 解析
XPath 是在 XML eXtensible Markup Language )⽂档中查找信息的⼀种语法, XML HTML 类似也是⼀种⽤标签承载数据的标签语⾔,不同之处在于XML 的标签是可扩展的,可以⾃定义的,⽽且 XML 对语法有更严格的要求。XPath 使⽤路径表达式来选取 XML ⽂档中的节点或者节点集,这⾥所说的节点包括元素、属性、⽂本、命名空间、处理指令、注释、根节点等。下⾯我们通过⼀个例⼦来说明如何使⽤XPath对⻚⾯进⾏解析。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
 <book>
 <title lang="eng">Harry Potter</title>
 <price>29.99</price>
 </book>
 <book>
 <title lang="eng">Learning XML</title>
 <price>39.95</price>
 </book>
</bookstore>
对于上⾯的 XML ⽂件,我们可以⽤如下所示的 XPath 语法获取⽂档中的节点。

XPath还⽀持通配符⽤法,如下所示。

 如果要选取多个节点,可以使⽤如下所示的⽅法。

 

说明 :上⾯的例⼦来⾃于 菜⻦教程 ⽹站上的 XPath 教程 ,有兴趣的读者可以⾃⾏阅读原⽂。 当然,如果不理解或不熟悉 XPath 语法,可以在浏览器的开发者⼯具中按照如下所示的⽅法查看元素的XPath语法,下图是在 Chrome 浏览器的开发者⼯具中查看⾖瓣⽹电影详情信息中影⽚标题的 XPath 语法。

实现XPath解析需要三⽅库 lxml 的⽀持,可以使⽤下⾯的命令安装 lxml

pip install lxml

 下⾯我们⽤XPath解析⽅式改写之前获取⾖瓣电影Top250的代码,如下所示。

import random
import time
from lxml import etree
import requests
for page in range(1, 11):
 resp = requests.get(
 url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
 headers={
 'User-Agent': 'BaiduSpider',
 }
 )
 tree = etree.HTML(resp.text)
# 通过XPath语法从⻚⾯中提取需要的数据
 spans = tree.xpath('//*
[@id="content"]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]')
 for span in spans:
 print(span.text)
 time.sleep(random.randint(1, 3))

 

CSS 选择器解析
对于熟悉 CSS 选择器和 JavaScript 的开发者来说,通过 CSS 选择器获取⻚⾯元素可能是更为简单的选择,因为浏览器中运⾏的JavaScript 本身就可以 document 对象的 querySelector() querySelectorAll() ⽅法基于CSS 选择器获取⻚⾯元素。在 Python 中,我们可以利⽤三⽅库 bs4 BeautifulSoup )或 pyquery 来做同样的事情。 BeautifulSoup 可以⽤来解析 HTML XML ⽂档,修复含有未闭合标签等错误的⽂档,通过为待解析的⻚⾯在内存中创建⼀棵树结构,实现对从⻚⾯中提取数据操作的封装。可以⽤下⾯的命令来安装BeautifulSoup
pip install beautifulsoup4
下⾯是使⽤ bs4 改写的获取⾖瓣电影 Top250 电影名称的代码。
import random
import time
import bs4
import requests
for page in range(1, 11):
 resp = requests.get(
 url=f'https://movie.douban.com/top250?start={(page - 1) * 25}',
 headers={
 'User-Agent': 'BaiduSpider',
 }
 )
 soup = bs4.BeautifulSoup(resp.text, 'lxml')
 # 通过CSS选择器从⻚⾯中提取需要的数据
 spans = soup.select('div.info > div.hd > a > span:nth-child(1)')
 for span in spans:
 print(span.text)
 time.sleep(random.randint(1, 3))
关于 BeautifulSoup 更多的知识,可以参考它的 官⽅⽹站
简单的总结
下⾯我们对三种解析⽅式做⼀个简单⽐较。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值