相信每一位初学爬虫的小羊都会对网页HTML文档的解析感到头疼,不知道lxml、BeautifulSoup和pyquery这三个库的解析原理,下面正羊羊就讲一讲对这个网页解析过程的理解和这三个库的基本使用啦。
首先,这个网页解析是指对网页内容的提取,比如链家网上的房源信息,如下图,画红框的是我们要的信息。
然后按F12打开浏览器的监控台,或者是在红框的字体上右键点击“检查”,可以看到网页代码如下:
(先不用理会里面的代码是讲啥,不过可以留意里面的中文就是我们要的信息)
我们可以看到,每个中文信息前面,都会有红框圈起来的“标签”,像是
当然,仅靠这些标签还不行,每个标签下面依照信息的种类有不同的类别,<div标签下就分了不同的类别class:
像是这红框里面的就是不同的类别了。前面说的三种第三方库的作用,就是根据这些标签以及标签下的不同分类,提取出我们需要的信息。
所以,要想用好这三个第三方库,我们就得了解含这些标签的框架结构。
回看前面的几幅网页代码图,我们可以发现,<div标签前面的缩进是不一样的,有些前面还有一个倒三角符号。我们在网页监控台上点击这些倒三角的符号,可以让下面有进一步缩进的信息收起或展开。这也就表明,标签与标签之间,存在着一种递归关系。还是上一幅图,正羊羊将一些标签标个号,方便下面的讲解。
首先,标签1和标签2的缩进不同,由标签1引申出标签2,进一步,标签2引申出标签3~8,而标签3~8属同一级别。从而,这8个标签有如下的引申关系:
我们将各个标签成为“节点”,用亲缘关系来表达各个节点之间的关系。其中,标签1相对于标签2来讲是“父节点”(parent),标签2相对于标签1来讲是“子节点”(children)。同理,标签3~8是标签2的子节点(childrens)。在标签3~8中,各个节点互为兄弟节点(sibling),他们都是标签1的子孙节点(descendant),标签1是他们的祖节点(ancestor)。
(前文所列的英文为程序中所用名词,与英语的语法和意义无关。)
有了上面所述的知识,我们就可以用解析库啦。
lxml
为讲解方便,我们采用下图所示的HTML代码:
首先来看下这里面的标签,分别是<div>、<ul>、<li>、<a>,这四个标签层级依次递减,最外层为<div>,最内层为<a。有如下的引申关系:
程序上先导入lxml库,然后列举出<li节点下的内容:
蓝色框中有以<li为标签的3个条目,结果也输出了含3个元素的列表。这些元素表示节点<li为Element类型。(这个不重要,可以不用管)
现在我们需要留意到,这段HTML文本中的每段字符,都会由尖括号<>包围起来,除了节点
在lxml库里,这里的“item”信息被定义成text,我们用text()来表示这些文本。
就这样,我们将需要的3个“item”给提取了出来。
这里提取的原理其实很简单,就是按照标签一个跟着一个地对应起来,用text()表示要提取的信息,让xpath把这条字符串和原文匹配起来,输出每一个text()表示的内容。
举个栗子,我们把上面xpath中用于匹配的字符串改一下,把li前面的//变为/:
这是因为在li节点里没有文本,只有属于节点a的文本,所以匹配不到。如果觉得难以理解,就权且让匹配字符串开头都是//吧。
前面我们说到,紧靠标签来定位信息还是不够的,我们还需要标签里的属性,像是class。属性的匹配方法示例如下:
这就是获取a节点下属性href为”link2.html”的文本的方法。
更多功能请参照官方文档:https://lxml.de/
BeautifulSoup
相对于xpath,BeautifulSoup操作起来会容易得多,它不需要//和/这些符号来一一匹配标签(节点),而是根据属性来直接挑出文本信息。我们用下面这段HTML代码来演示:
图中红框里面的是我们关心的信息。有一点要留意,HTML代码中每个节点有相应的节点来闭合,像是第一个红框里的节点<title>,会由</title>来闭合,像是<head>、<p>、<a>都有闭合,但是<html>和<body>却没有,我们先来用BeautifulSoup来解析这段HTML文本:
可以看到,BeautifulSoup自动把</body>和</html>补齐了,这也是这个库的优点之一。
现在我们可以对里面的内容进行解析了:
可以看到,我们可以直接用标签<title>和文本代名词string来取出我们要的文本,这里的string的作用和前面说的text()作用是一样的。
在这段HTML代码中,我们可以了解到节点b的父节点为节点p,那么我们就提取p中的属性name的值:
因为是要从节点b连接到节点p,而p是b的父节点(parent),从而,用b.parent,所需信息是p中的属性(attrs),名称为name,故而用b.parent.attrs[‘name’]。显然,如果是属性class,那么方括号(索引)里的就是’class’了。
更多用法请参考官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
pyquery
这个库比BeautifulSoup更强大,这体现在其对信息的选取能力要更强。对HTML的初步解析(初始化)方法有多种,可以导入HTML文本,也可以直接写入要解析的网站网址,当然也可以让程序直接解析html文件:
具体的解析方法可以直接去看官网啦!
https://pyquery.readthedocs.io/en/latest/
看更多内容,欢迎关注公众号“正羊羊部落”