[Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解

2021-12-02 20:39:06 浏览数 (1)

文章目录:

  • 一.安装BeautifulSou
  • 二.快速开始BeautifulSoup解析
  • 三.深入了解BeautifulSoup爬虫
  • 四.BeautifulSoup简单爬取个人博客网站
  • 五.总结

一.安装BeautifulSoup

BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python扩展库。BeautifulSoup通过合适的转换器实现文档导航、查找、修改文档等。它可以很好的处理不规范标记并生成剖析树(Parse Tree);它提供的导航功能(Navigating),可以简单又快速地搜索剖析树以及修改剖析树。BeautifulSoup技术通常用来分析网页结构,抓取相应的Web文档,对于不规则的HTML文档,它提供了一定的补全功能,从而节省了开发者的时间和精力。本章将带领您走进BeautifulSoup爬虫的海洋,下面先简单介绍BeautifulSoup技术的安装过程。

1.安装过程

BeautifulSoup安装主要通过pip指令进行。如下图所示,在命令提示符CMD环境下,通过cd命令进入Python3.7安装目录的Scripts文件夹下,再调用“pip install bs4”命令安装,bs4即BeautifulSoup4。安装命令如下:

  • cd C:Software...Python37Scripts
  • pip install bs4

当BeautifulSoup扩展包安装成功后,在Python3.7中输入“from bs4 import BeautifulSoup”语句导入该扩展包,测试安装是否成功,如果没有异常报错即安装成功,如下图所示。

输入代码如下:

  • from bs4 import BeautifulSoup

BeautifulSoup有两个常用版本:BeautifulSoup 3和BeautifulSoup 4(简称BS4)。BeautifulSoup 3目前已经停止开发,项目中使用更多的是BeautifulSoup 4,现已移植到BS4扩展包中。建议读者安装BeautifulSoup4,因为BeautifulSoup3已经停止更新;同时如果读者使用的是Anaconda等集成开发环境,它的BeautifulSoup扩展包是已经安装了的,可以直接使用。

BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml,另一个可供选择的解析器是纯Python实现的html5lib,html5lib的解析方式与浏览器相同。Windows系统下调用pip或easy_install命令安装lxml,代码如下:

  • pip install lxml
  • easy_install lxml

下表列出了BeautifulSoup官方文档中主要的解析器和它们的优缺点。


2.pip安装扩展包用法

前面的安装过程调用pip命令,那么它究竟是什么呢?pip是一个现代的、通用的Python包管理工具,提供了对Python包(Package)的查找、下载、安装及卸载功能。Python可以通过easyinstall或者pip命令安装各种各样的包,其中easyinsall提供了“傻瓜式”的在线一键安装模块的方式,而pip是easy_install的改进版,提供更好的提示信息以及下载、卸载Python包等功能,常见用法如下表所示。

在Python2旧版本开发环境中使用pip命令之前,需要安装pip软件(下载pip-Win_1.7.exe软件直接安装),再调用pip命令对具体的扩展包进行安装,目前Python3已经内嵌pip工具供大家直接使用。

  • http://pypi.python.org/pypi/pip#downloads

Python2旧版本安装完pip工具后,它会在Python安装目录下添加Scripts目录。在Python2.7中,安装的扩展包会在目录Scripts文件夹下添加相应的文件,甚至需要将此目录(Scripts)加入环境变量中。安装pip成功后,通过命令“pip install bs4”安装BeautifulSoup 4软件。

下表显示了pip常用命令,其中最常用的命令是“install”和“uninstall”。

最后推荐官方文档:

  • https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
  • https://pypi.org/project/beautifulsoup4/

二.快速开始BS解析

下面这段HTML代码(test04_01.html)是关于李白的一首诗和描述,它将作为例子被多次使用。HTML主要采用节点对的形式进行编写,如<html></html>、<body></body>、<a></a>等。

代码语言:javascript复制
<html>
  <head>
    <title>BeautifulSoup技术</title>
  </head>
  <body>
  <p class="title"><b>静夜思</b></p>
  <p class="content">
    窗前明月光,<br />
    疑似地上霜。<br />
    举头望明月,<br />
    低头思故乡。<br />
  </p>
  <p class="other">
    李白(701年-762年),字太白,号青莲居士,又号“谪仙人”,
    唐代伟大的浪漫主义诗人,被后人誉为“诗仙”,与
    <a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>
    并称为“李杜”,为了与另两位诗人
    <a href="http://example.com/lishangyin" class="poet" id="link2">李商隐</a>、
    <a href="http://example.com/dumu" class="poet" id="link3">杜牧</a>即“小李杜”区别,
    杜甫与李白又合称“大李杜”。
    其人爽朗大方,爱饮酒...</p>
  <p class="story">...</p>

通过浏览器打开该网页显示如下图所示。


1.BeautifulSoup解析HTML

下列代码是通过BeautifulSoup解析这段HTML网页,创建一个 BeautifulSoup对象,然后调用BeautifulSoup包的prettify()函数格式化输出网页。

代码语言:javascript复制
# coding=utf-8
from bs4 import BeautifulSoup

#HTML源码
html = """
<html>
  <head>
    <title>BeautifulSoup技术</title>
  </head>
  <body>
  <p class="title"><b>静夜思</b></p>
  <p class="content">
    窗前明月光,<br />
    疑似地上霜。<br />
    举头望明月,<br />
    低头思故乡。<br />
  </p>
  <p class="other">
    李白(701年-762年),字太白,号青莲居士,又号“谪仙人”,
    唐代伟大的浪漫主义诗人,被后人誉为“诗仙”,与
    <a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>
    并称为“李杜”,为了与另两位诗人
    <a href="http://example.com/lishangyin" class="poet" id="link2">李商隐</a>、
    <a href="http://example.com/dumu" class="poet" id="link3">杜牧</a>
    即“小李杜”区别,杜甫与李白又合称“大李杜”。
    其人爽朗大方,爱饮酒...
  </p>
  <p class="story">...</p>
"""

#按照标准的缩进格式的结构输出
soup = BeautifulSoup(html)
print(soup.prettify())

代码输出结果如下所示,是网页的HTML源代码。soup.prettify()将soup内容格式化输出,用BeautifulSoup 解析HTML文档时,它会将HTML文档类似DOM文档树一样处理。

注意:前面定义的HTML源码标签对是缺少结束标签的,但是使用prettify()函数输出的结果已经自动补齐了结束标签,这是BeautifulSoup的一个优点。BeautifulSoup即使得到了一个损坏的标签,它也产生一个转换DOM树,并尽可能和您原文档内容含义一致,这种措施通常能够帮助您更正确地搜集数据。另外,我们还可以用本地HTML文件来创建BeautifulSoup对象,代码如下所示:

  • soup = BeautifulSoup(open('test04_01.html'))

2.简单获取网页标签信息

当我们已经使用BeautifulSoup解析了网页之后,如果您想获取某个标签之间的信息,怎么实现呢?比如获取标签<title>和</title>标题内容。下面的test02.py代码就将教大家使用BeautifulSoup技术获取标签信息的用法,更系统的知识将在第三部分介绍。

代码语言:javascript复制
# coding=utf-8
from bs4 import BeautifulSoup

#创建本地文件soup对象
soup = BeautifulSoup(open('test04_01.html'), "html.parser")
#获取标题
title = soup.title
print('标题:', title)

该段代码获取HTML的标题,输出结果为“<title>BeautifulSoup技术</title>”。同样,可以获取其他标签,如HTML的头部(head)。

代码语言:javascript复制
#获取标题
head = soup.head
print('头部:', head)

输出结果为“<head><title>BeautifulSoup技术</title></head>”。再比如获取网页中的超链接,通过调用“soup.a”代码获取超链接(<a>)。

代码语言:javascript复制
#获取a标签
ta = soup.a
print('超链接内容:', ta)

输出为:

  • <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a>

其中HTML中包括三个超链接,分别对应杜甫、李商隐、杜牧,而soup.a只返回第一个超链接。那么,如果想获取所有的超链接,怎么写代码实现呢?后面介绍的find_all()函数就可以实现。最后给出输出第一个段落(< p>)的代码。

代码语言:javascript复制
#获取p标签
tp = soup.p
print('段落内容:', tp)

输出结果为“<p class="title"><b>静夜思</b></p>”,其中unicode()函数用于转码,否则输出中文乱码。上面代码输出内容如下图所示。


3.定位标签并获取内容

前面部分简单介绍了BeautifulSoup标签,可以获取title、p、a等标签内容,但是如何获取这些已经定位了的指定标签对应的内容呢?下面这段代码是获取网页中所有的超链接标签及对应的url内容。

代码语言:javascript复制
#从文档中找到<a>的所有标签链接
for a in soup.find_all('a'):
    print(a)

#获取<a>的超链接
for link in soup.find_all('a'):  
    print(link.get('href'))

输出结果如下图所示。find_all('a')函数是查找所有< a>标签,并通过for循环输出结果;第二个for循环是通过“link.get('href')”代码获取超链接标签中的url网址。

比如:

  • <a class="poet" href="http://example.com/dufu" id="link1">杜甫< /a>

通过调用findall('a')函数获取所有超链接的HTML源码,再调用get('href')获取超链接的内容,href属性对应的值为:http://example.com/dufu。如果想获取文字内容,则调用gettext()函数。

代码语言:javascript复制
for a in soup.find_all('a'):
print a.get_text()

输出结果为< a>和< /a>之间的链接内容,即如下所示。

  • 杜甫
  • 李商隐
  • 杜牧

后面文章将详细介绍具体的定位节点方法,结合实际例子进行分析讲解。


三.深入了解BS爬虫

第一部分我们介绍了BeautifulSoup爬虫的安装过程及简介,第二部分我们又快速学习了BeautifulSoup技术,而这部分将深入介绍BeautifulSoup技术的语法及用法。

1.BeautifulSoup对象

BeautifulSoup将复杂的HTML文档转换成一个树形结构,每个节点都是Python对象,BeautifulSoup官方文档将所有的对象归纳为以下四种:

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

下面我们开始详细介绍。

1.Tag

Tag对象表示XML或HTML文档中的标签,通俗地讲就是HTML中的一个个标签,该对象与HTML或XML原生文档中的标签相同。Tag有很多方法和属性,BeautifulSoup中定义为soup.Tag,其中Tag为HTML中的标签,比如head、title等,其结果返回完整的标签内容,包括标签的属性和内容等。例如:

上面HTML代码中,title、p、a等都是标签,起始标签(<title>、<p>、<a>)和结束标签(</title>、</p>、</a>)之间加上内容就是Tag。标签获取方法代码如下:

通过BeautifulSoup对象读者可以轻松地获取标签和标签内容,这比我们前一章的正则表达式爬虫方便很多。同时注意,它返回的内容是所有标签中的第一个符合要求的标签,比如“print soup.a”语句返回第一个超链接标签。

下面这行代码是输出该对象的类型,即Tag对象。

代码语言:javascript复制
print type(soup.html)
# <class 'BeautifulSoup.Tag'>

Tag有很多方法和属性,在遍历文档树和搜索文档树中有详细讲解。现在介绍一下Tag中最重要的属性:name和attrs。

(1)name

name属性用于获取文档树的标签名字,如果想获取head标签的名字,只要使用soup.head.name代码即可,对于内部标签,输出的值便为标签本身的名称。soup对象本身比较特殊,它的name为document,代码如下:

(2)attrs

attrs是属性(attributes)的英文简称,属性是网页标签的重要内容。一个标签(Tag)可能有很多个属性,例如上面的例子:

代码语言:javascript复制
<a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>

它存在两个属性,一个是class属性,对应的值为“poet”;一个是id属性,对应的值为“link1”。Tag属性操作方法与Python字典相同,获取p标签的所有属性代码如下,得到一个字典类型的值,它获取的是第一个段落p的属性及属性值。

代码语言:javascript复制
print(soup.p.attrs)
#{u'class': [u'title']}

如果需要单独获取某个属性,使用如下两种方法获取超链接的class属性值。

代码语言:javascript复制
print(soup.a['class'])
#[u'poet']
print(soup.a.get('class'))
#[u'poet']

下图为HTML源代码,获取第一个超链接为class='poet'。

BeautifulSoup每个标签tag可能有很多个属性,可以通过“.attrs”获取属性,tag的属性可以被修改、删除或添加。下面举个简单的例子进行介绍,完整代码为test03.py文件。

代码语言:javascript复制
# coding=utf-8
from bs4 import BeautifulSoup
soup = BeautifulSoup('<b class="test" id="yxz">Eastmount</b>',
           "html.parser")
tag = soup.b
print(tag)
print(type(tag))

#Name
print(tag.name)
print(tag.string)

#Attributes
print(tag.attrs)
print(tag['class'])
print(tag.get('id'))

#修改属性 增加属性name
tag['class'] = 'abc'
tag['id'] = '1'
tag['name'] = '2'
print(tag)

#删除属性
del tag['class']
del tag['name']
print(tag)
print(tag['class'])
#KeyError: 'class'

输出结果如图所示,包括修改属性class、id,增加属性name,删除属性class、name等结果。

注意:HTML定义了一系列可以包含多个值的属性,最常见的可以包含多个值的属性是 class,还有一些属性如rel、rev、accept-charset、headers、accesskey等,BeautifulSoup中多值属性的返回类型是list,具体操作请读者在BeautifulSoup官网进行学习。


2.NavigableString

前面讲述了获取标签的Name和Attributes,那么如果想获取标签对应的内容,怎么实现呢?你可能已经猜到了,使用string属性即可获取标签<>与之间的内容。比如:

代码语言:javascript复制
print(soup.a['class'])
#[u'poet']
print(soup.a['class'].string)
#杜甫

获取“<a href="http://example.com/dufu" class="poet" id="link1">杜甫</a>”之间的内容,它是不是比前一篇文章介绍的正则表达式方便很多。

BeautifulSoup用NavigableString类来包装tag中的字符串,NavigableString表示可遍历的字符串。一个NavigableString字符串与Python中的Unicode字符串相同,并且支持包含在遍历文档树和搜索文档树中的一些特性。利用下述代码可以查看NavigableString的类型。

代码语言:javascript复制
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('test04_01.html'), "html.parser")
tag = soup.title
print(type(tag.string))
#<class 'BeautifulSoup.NavigableString'>

注意,旧版本Python2需要通过unicode()方法可以直接将NavigableString对象转换成Unicode字符串,再进行相关的操作。如果标签中包含的字符串不能编辑,但是可以被替换成其他的字符串,用replace_with()方法实现。代码如下:

代码语言:javascript复制
tag.string.replace_with("替换内容")  
print(tag)
#<title>替换内容</title>

replace_with()函数将“< title>BeautifulSoup技术< /title>”中的标题内容由“BeautifulSoup技术”替换成了“替换内容”。NavigableString对象支持遍历文档树和搜索文档树中定义的大部分属性,而字符串不能包含其它内容(tag对象却能够包含字符串或是其它tag),字符串不支持“.contents”或“.string ”属性或find()方法。

提醒:在旧版本Python2中,如果想在BeautifulSoup之外使用NavigableString对象,需要调用unicode()方法,将该对象转换成普通的Unicode字符串,否则就算BeautifulSoup的方法已经执行结束,该对象的输出也会带有对象的引用地址,从而浪费内存。


3.BeautifulSoup

BeautifulSoup对象表示的是一个文档的全部内容,通常情况下把它当作Tag对象,该对象支持遍历文档树和搜索文档树中描述的大部分的方法,详见下一小节。下面代码是输出soup对象的类型,输出结果就是BeautifulSoup对象类型。

代码语言:javascript复制
print(type(soup))
# <class 'BeautifulSoup.BeautifulSoup'>

注意:因为 BeautifulSoup 对象并不是真正的HTML或XML的标签tag,所以它没有name和attribute属性。但有时查看它的“.name”属性是很方便的,故BeautifulSoup对象包含了一个值为“[document]”的特殊属性“soup.name”。下述代码即是输出BeautifulSoup对象的name属性,其值为“[document]”。

代码语言:javascript复制
print(soup.name)
# u'[document]'

4.Comment

Comment对象是一个特殊类型的NavigableString对象,它用于处理注释对象。下面这个示例代码用于读取注释内容,代码如下:

代码语言:javascript复制
markup = "<b><!-- This is a comment code. --></b>"  
soup = BeautifulSoup(markup, "html.parser")
comment = soup.b.string  
print(type(comment)) 
# <class 'bs4.element.Comment'>
print(comment)  
# This is a comment code.

输出结果如下图所示:


2.遍历文档树

介绍完这四个对象后,下面简单介绍遍历文档树和搜索文档树及常用的函数。在BeautifulSoup中,一个标签(Tag)可能包含多个字符串或其它的标签,这些称为这个标签的子标签,下面从子节点开始介绍。

1.子节点

BeautifulSoup中通过contents值获取标签(Tag)的子节点内容,并以列表形式输出。以test04_01.html代码为例,获取标签子节点内容代码如下:

代码语言:javascript复制
# coding=utf-8
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('test04_01.html'), "html.parser")
print(soup.head.contents)
#['n', <title>BeautifulSoup技术</title>, 'n']

由于标题间< title>和< /title>存在两个换行,所以获取的列表包括了两个换行,如个需要提取第二个元素,代码如下:

另一个获取子节点的方法是children关键字,但它返回的不是一个list,可以通过for循环来获取所有子节点内容。方法如下:

代码语言:javascript复制
print(soup.head.children)
for child in soup.head.children:
    print(child)
#<listiterator object at 0x00000000027335F8>

前面介绍的contents和children属性仅包含标签的直接子节点,如果需要获取Tag的所有子节点,甚至是孙节点,则需要使用descendants属性,方法如下:

代码语言:javascript复制
for child in soup.descendants:
    print(child)

输出如下图所示,所有的HTML标签都打印出来。


2.节点内容

如果标签只有一个子节点,需要获取该子节点的内容,则使用string属性,输出子节点的内容,通常返回最里层的标签内容。比如获取标题内容如下:

代码语言:javascript复制
print(soup.head.string)
# None
print(soup.title.string)
# BeautifulSoup技术

当标签包含多个子节点时,Tag就会无法确定string获取哪个子节点的内容,此时输出的结果就是None,比如获取< head>的内容,返回值就是None,因为包括了两个换行元素。如果需要获取多个节点内容时,则使用strings属性,示例如下:

代码语言:javascript复制
for content in soup.strings:
    print(content)

但是输出的字符串可能包含多余的空格或换行,这里需要使用stripped_strings方法去除多余的空白内容,代码如下:

代码语言:javascript复制
for content in soup.stripped_strings:
    print(content)

运行结果如图所示。


3.父节点

调用parent属性定位父节点,如果需要获取节点的标签名则使用parent.name,代码如下所示:

代码语言:javascript复制
p = soup.p
print(p.parent)
print(p.parent.name)
#<p class="story">...</p></body>
#body

content = soup.head.title.string
print(content.parent)
print(content.parent.name)
#<title>BeautifulSoup技术</title>
#title

如果需要获取所有的父节点,则使用parents属性循环获取,代码如下:

代码语言:javascript复制
content = soup.head.title.string
for parent in content.parents:
    print(parent.name)

4.兄弟节点

兄弟节点是指和本节点位于同一级的节点,其中nextsibling 属性是获取该节点的下一个兄弟节点,previoussibling 则与之相反,取该节点的上一个兄弟节点,如果节点不存在,则返回None。

  • print(soup.p.next_sibling)
  • print(soup.p.prev_sibling)

注意:实际文档中的tag的nextsibling 和previoussibling 属性通常是字符串或空白,因为空白或者换行也可以被视作一个节点,所以得到的结果可能是空白或者换行。同理,通过nextsiblings和previoussiblings属性可以获取当前节点的所有兄弟节点,再调用循环迭代输出。


5.前后节点

调用属性nextelement可以获取下一个节点,调用属性previouselement可以获取上一个节点,代码举例如下:

  • print(soup.p.next_element)
  • print(soup.p.previous_element)

同理,通过nextsiblings和previouselements属性可以获取当前节点的所有兄弟节点,并调用循环迭代输出。注意,如果提示错误“TypeError: an integer is required”,则需要增加unicode()函数转换成中文编码输出。


3.搜索文档树

搜索文档树作者主要讲解findall()方法,这是最常用的一种方法,而更多的方法与遍历文档树类似,包括父节点、子节点、兄弟节点等,推荐读者下来从官网自行学习。如果想从网页中得到所有的标签,使用find_all()方法的代码如下:

代码语言:javascript复制
urls = soup.find_all('a')
for u in urls:
    print(u)
# <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a>
# <a class="poet" href="http://example.com/lishangyin" id="link2">李商隐</a>
# <a class="poet" href="http://example.com/dumu" id="link3">杜牧</a>

输出结果如下图所示:

注意:如果你报错“‘NoneType’ object is not callable using ‘find_all’ in BeautifulSoup”,其原因是需要安装BeautifulSoup4版本或bs4,因为方法find_all()是属于该版本。而BeautifulSoup3使用的方法如下所示:

  • from BeautifulSoup import BeautifulSoup
  • soup.findAll('p', align="center")

同样,该函数支持传入正则表达式作为参数,BeautifulSoup会通过正则表达式的match() 来匹配内容。下面例子找出所有以b开头的标签示例:

代码语言:javascript复制
import re
for tag in soup.find_all(re.compile("^b")):
print(tag.name)
# body
# b
# br
# br

其输出结果包括字母“b”的标签名,如body、b、br、br等。如果想获取标签a和标签b的值,则使用下面的函数:

  • soup.find_all(["a", "b"])

注意find_all()函数是可以接受参数进行指定节点查询的,代码如下:

代码语言:javascript复制
soup.find_all(id='link1')
# <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a>

也可以接受多个参数,比如:

代码语言:javascript复制
soup.find_all("a", class_="poet")
# <a class="poet" href="http://example.com/dufu" id="link1">杜甫</a>
# <a class="poet" href="http://example.com/lishangyin" id="link2">李商隐</a>
# <a class="poet" href="http://example.com/dumu" id="link3">杜牧</a>

讲到这里,BeautifulSoup基础知识及用法已经讲述完毕,接下来通过一个简单示例讲解BeautifulSoup爬取网络数据,这里抓取的是上一篇文章的那个示例,爬取作者个人博客的首页信息。同时,更多BeautifulSoup技术知识推荐大家去其官方网站学习,网址为:

  • http://beautifulsoup.readthedocs.io/zh_CN/latest/

四.BeautifulSoup简单爬取个人博客网站

上一篇文章讲述了正则表达式爬取个人博客网站的简单示例,下面讲解BeautifulSoup技术爬取个人博客网站内容。BeautifulSoup提供了一些方法以及类Python语法来查找一棵转换树,帮助你解析一棵树并定位获取你所需要的内容。作者的个人网站网址为:

  • http://www.eastmountyxz.com/

现在需要爬取博客首页中四篇文章的标题、超链接及摘要内容,比如标题为“再见北理工:忆北京研究生的编程时光”。

首先,通过浏览器定位这些元素源代码,发现它们之间的规律,这称为DOM树文档节点树分析,找到所需爬取节点对应的属性和属性值,如图所示。

标题位于<div class="essay"></div>位置下,它包括一个<h1></h1>记录标题,一个<p></p>记录摘要信息,其余三篇文章节点为<div class="essay1"></div>、<div class="essay2"></div>和<div class="essay3"></div>。现在需要获取第一篇文章标题、超链接和摘要的代码如下:

代码语言:javascript复制
# -*- coding: utf-8 -*-
import re 
import urllib.request
from bs4 import BeautifulSoup

url = "http://www.eastmountyxz.com/"
page = urllib.request.urlopen(url)
soup = BeautifulSoup(page, "html.parser")
essay0 = soup.find_all(attrs={"class":"essay"})
for tag in essay0:
    print(tag)
    print('')  #换行
    print(tag.a)
    print(tag.find("a").get_text())
    print(tag.find("a").attrs['href'])
    content = tag.find("p").get_text()
    print(content.replace(' ',''))
print('')

输出结果如下图所示,其中代码soup.findall(attrs={"class":"essay"})用于获取节点< div class="essay">的内容,然后采用循环输出,但该class类型只包括了一段内容。接着再定位div中的超链接,通过tag.find("a").gettext()获取内容,tag.find("a").attrs['href']获取超链接url,最后获取段落摘要。

同理,爬取其余文章的代码如下,通过循环获取essay1、essay2、essay3内容,这些div布局中的格式都一样,包括一个标题和一个摘要信息,代码如下:

代码语言:javascript复制
#整理输出
i = 1
while i<=3:
    num = "essay"   str(i)
    essay = soup.find_all(attrs={"class":num})
    for tag in essay:
        print(tag.find("a").get_text())
        print(tag.find("a").attrs['href'])
        content = tag.find("p").get_text()
        print(content.replace(' ',''))
    i  = 1
    print('')

输出结果如下:

整个BeautifulSoup爬虫已经讲完了,是不是比前面的正则表达式方便很多,而且爬取的函数也更加智能。后面将结合案例深入讲解BeautifulSoup实际操作,包括爬取电影信息、存储数据库等内容。


五.本章小结

BeautifulSoup是一个可以从HTML或XML文件中提取所需数据的Python库,这里作者把它看作是一种技术。

  • 一方面是它具有智能化爬取网页信息的强大功能,对比前面的正则表达式爬虫,您就能体会到它的便捷和适用性,BeautifulSoup通过载入整个网页文档并调用相关函数定位所需信息的节点,再爬取相关内容.
  • 另一方面,BeautifulSoup使用起来比较简单,API非常人性化,采用类似于XPath的分析技术定位标签,并且支持CSS选择器,开发效率相对较高,被广泛应用于Python数据爬取领域。所以作者把它看作一种爬虫技术,接下来通过一个完整的爬虫案例加深读者的印象。

该系列所有代码下载地址:

  • https://github.com/eastmountyxz/Python-zero2one

参考文献如下:

  • 书籍《Python网络数据爬取及分析从入门到精通》
  • 作者博客:https://blog.csdn.net/Eastmount

0 人点赞