网络爬虫入门(四):解析网页

在我们已经可以将网页资源下载到本地后,就可以进行我们的第二部操作了,即将网页中我们需要的资源进行解析(上一节的selenium中也有提及)。本篇内容总结了其他三种常用的解析网页方式。

一、正则表达式

正则表达式是最常用的解析字符串的方法,它通过定义了一系列的正则字符来代表一些特殊的含义。

标识符描述标识符描述.匹配任意字符,除了换行符\s匹配空白字符*匹配前一个字符0次或多次\S匹配任何非空白字符+匹配前一个字符1次或多次\d匹配数字,等价于[0-9]?匹配前一个字符0次或1次\D匹配任何非数字,等价于[^0-9]^匹配字符串开头\w匹配字母数字,等价于[A-Za-z0-9_]$匹配字符串末尾\W匹配非字母数字,等价于[^A-Za-z0-9_]()匹配括号内的表达式,也表示一个组[]用来表示一组字符

python3自带了正则匹配函数库,直接引用即可

import re

re库中有很多匹配函数,常用的是match、search和findall方法

'''

match方法从字符串起始位置匹配一个模式,如果从起始位置匹配不到就返回none

pattern是正则表达式、string是待匹配的字符串、flags是匹配模式

'''

re.match(pattern, string, flags=0)

# search方法将扫描整个字符串,并返回第一个成功的匹配

re.search(pattern, string, flags=0)

# findall方法可以找到所有的匹配项,以列表的形式返回

re.findall(pattern, string, flags=0)

二、BeautifulSoup解析

BeautifulSoup可以从HTML和XML文件中提取数据,它可以通过解析文档为用户提供需要抓取的数据。

首先需要安装BeautifulSoup库

pip install bs4

BeautifSoup中使用了几种解析器,其中最常用也是比较好用的就是lxml解析库,一般推荐使用

from bs4 import BeautifulSoup

# 获取网页资源

......

r = request(...)

# BeautifulSoup将网页响应体的字符串转化成soup对象,再利用soup自带的库函数进行解析

soup = BeautifulSoup(r.text,"lxml")

# 寻找目标

content = soup.find("标签名称", class_="类名称").text.strip()

# strip是去除字符串两边空白符,find()也可以换成find_all()来表示所有的结果

事实上,soup对象是一个树结构,每一个结点都是一个python对象,获取网页的内容就是一个提取对象内容的过程。具体方法有三种:遍历文档树、搜索文档树和CSS选择器

其中遍历文档树的方法并不是很常用,主要还是剩下两种方式用的比较多。而搜索文档树主要就是用find和findall两种方法进行搜素,这里不再多提。主要说一下CSS选择器方法

使用CSS选择器方法相对较灵活,主要通过select方法实现

soup.select("header h1")

soup.select("header > h1")

其中select方法也支持使用正则表达式的搜索方式

soup.select('a[href^="http:...."]')

# 搜索指定的标签

三、使用lxml解析网页

最后我们简单了解一下lxml解析库,他使用了C语言编写,也是一种效率比较高的解析方法,速度比不用lxml解析器的BeautifulSoup快一些。

首先lxml也是需要安装的

pip install lxml

其次,lxml提取网页代码数据也有三种方式:XPath选择器、CSS选择器和BeautifulSoup的find()方法。由于后两种方法和BeautifulSoup方法相差不多,所以这里主要介绍一下XPath选择器

from lxml import etree

# 获取网页资源

r = request.get(.....)

html = etree.HTML(r.text)

content = html.xpath('//h1[@class="classname"]/a/text()')

print(content)

这里使用了xpath语法来选择需要的内容。其中“//h1”代表选取所有

中的子元素,“//”无论在文档中什么位置,后面加上[@class=“classname”]表示选取

中class为“classname”的元素,/a表示选取

子元素的元素,/text()表示提取元素中的所有文本。

不过,不管选择哪种方法,最终得到的结果都是一样的。从代码来看,lxml使用XPath的方法比较麻烦,而BeautifulSoup的find_all更加简单一些。 虽然XPath看起来比价麻烦,但Chrome的“检查”功能提供了很好查找XPath的工具。具体如下,找到需要的标签,然后右键,再在弹窗中找到Copy下的Copy xPath,即可快速获取xpath路径。这样配合lxml使用就更加方便了。

最后总结

总的来说,解析网页就是通过各种方式,定位到网页中的需要的标签内容,所以不管使用哪种方法都是可以的,主要看大家自己的使用习惯。三种方式的对比大致如下:

HTML 解析器性能易用性提取数据方式正则表达式快较难正则表达式BeautifulSoup快(使用lxml解析)简单Find方法和CSS选择器lxml快简单Xpath和CSS选择器