网页源代码抓取工具( 安装BeautifulSoup库的使用规则介绍及重点知识介绍库)

优采云 发布时间: 2022-03-18 10:11

  网页源代码抓取工具(

安装BeautifulSoup库的使用规则介绍及重点知识介绍库)

  

  BeautifulSoup 库

  虽然 XPath 比正则表达式使用起来更方便,但并不是最方便,只是更方便。我们的 BeautifulSoup 库可以让您更轻松地抓取您想要的内容。

  安装 BeautifulSoup 库

  在使用之前,还是老规矩先安装 BeautifulSoup 库。说明如下:

  pip install beautifulsoup4

  其中文开发文件:

  https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

  BeautifulSoup 库简介

  BeautifulSoup 库是一个强大的 Python 语言 XML 和 HTML 解析库。它提供了一些简单的函数来处理导航、搜索、修改解析树等。

  BeautifulSoup 库还可以自动将输入文档转换为 Unicode 编码,将输出文档自动转换为 UTF-8 编码。

  所以在使用BeautifulSoup库的过程中,开发时不需要考虑编码问题,除非你解析的文档没有指定编码方式,开发时需要进行编码处理。

  接下来详细介绍一下 BeautifulSoup 库的使用规则。

  选择翻译

  下面,我们来详细介绍一下 BeautifulSoup 库的关键知识。

  首先,BeautifulSoup 库中的一个重要概念是解释器的选择。因为它的底层依赖都是这些解释器,所以我们有必要去了解它们。博主特意列了一张表:

  口译员

  如何使用

  优势

  缺点

  Python 标准库

  BeautifulSoup(code,'html.parser')

  Python内置标准库,执行速度适中,容错能力强

  Python2.7.3 和 Python3.2.2 之前的版本容错性差

  lxml HTML解析器

  BeautifulSoup(代码,'lxml')

  解析速度快,容错能力强

  需要安装C语言库

  lxml XML解析器

  BeautifulSoup(代码,'xml')

  快速解析,唯一支持XML的解析器

  需要安装C语言库

  html5lib

  BeautifulSoup(代码,'html5lib')

  最佳容错性,以浏览器的方式解析文档,生成HTML5格式的文档

  解析很慢

  从上表可以看出,爬虫我们一般使用lxml HTML解析器。它不仅速度快,而且兼容性强。只是安装C语言库的一个缺点(不能叫缺点,应该叫麻烦)。

  基本用法

  使用BeautifulSoup库需要像其他库一样导入,但是虽然安装了beautifulsoup4,但是导入的名字不是beautifulsoup4,而是bs4。用法如下:

  from bs4 import BeautifulSoup

soup = BeautifulSoup('Hello World', 'lxml')

print(soup.h1.string)

  运行后,输出文本如下:

  

  节点选择器

  基本用法很简单,这里就不赘述了。下面开始详细学习BeautifulSoup库的所有重要知识点,第一个就是节点选择器。

  所谓节点选择器,就是直接通过节点名称来选择节点,然后使用字符串属性来获取节点中的文本,是最快的获取方式。

  例如,在基本用法中,我们使用 h1 直接获取 h1 节点,然后通过 h1.string 获取其文本。但是这种用法有一个明显的缺点,就是不适合复杂的关卡。

  因此,我们需要在使用节点选择器之前收缩文档。比如一个文档很大,但是我们获取的内容只是在id为blog的div中,那么非常适合我们先获取这个div,然后在div里面使用节点选择器。

  HTML 示例代码:

  

我是一个测试页面

我的主页

CSDN首页

Python板块

  在下面的示例中,我们仍然使用这段 HTML 代码来解释节点选择器。

  获取节点名称属性内容

  这里先教大家如何获取节点的name属性和内容。示例如下:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html, 'lxml')

# 获取节点的名称

print(soup.title.name)

# 获取节点的属性

print(soup.meta.attrs)

print(soup.meta.attrs['charset'])

# 获取节点的内容(如果文档有多个相同属性,默认获取第一个)

print(soup.a.string)

# 也可以一层一层的套下去

print(soup.body.ul.li.a.string)

  运行后效果如下:

  

  这里注释的代码很详细,这里不再赘述。

  获取所有子节点

  一般来说,一个节点的子节点可能有很多个,通过上述方法只能得到第一个。如果要获取一个标签的所有子节点,有两种方法。我们先来看代码:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html, 'lxml')

# 获取直接子节点

print("获取直接子节点")

contents = soup.head.contents

print(contents)

for content in contents:

print(content)

children = soup.head.children

print(children)

for child in children:

print(child)

  运行后效果如下:

  

  如上代码所示,我们有两种方式获取所有子节点,一种是通过contents属性,另一种是通过children属性,两种遍历的结果是一样的。

  但是需要特别注意,这里要获取所有的子节点,它会将换行符一起计算,所以在控制台输出中会看到很多空行。因此,在实际爬虫中,遍历时必须删除这些空行。

  获取所有后代节点

  由于可以得到直接的子节点,所以也可以得到所有的后代节点。BeautifulSoup 库为我们提供了 descendants 属性来获取后代节点。示例如下:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html, 'lxml')

# 获取ul的所有子孙节点

print('获取ul的所有子孙节点')

lis = soup.body.ul.descendants

print(lis)

for li in lis:

print(li)

  运行后效果如下:

  

  同样,后代在获取后代节点时也会计算换行符。重要的是要注意,descendants 属性将文本内容本身计为后代节点。

  父节点和兄弟节点

  同样,在实际的爬虫程序中,我们有时需要反向搜索父节点,或者搜索兄弟节点。

  BeautifulSoup库为我们提供了parent属性获取父节点,next_sibling属性获取当前节点的下一个兄弟节点,previous_sibling属性获取上一个兄弟节点。

  示例代码如下:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html, 'lxml')

# 获取第一个a标签的父亲节点的class属性

print(soup.a.parent['class'])

li1 = soup.li

li3 = li1.next_sibling.next_sibling.next_sibling.next_sibling

li2 = li3.previous_sibling.previous_sibling

print(li1)

print(li2)

print(li3)

for sibling in li3.previous_siblings:

print(sibling)

  运行后效果如下:

  

  前面说过,节点选择器也会把换行符'\n'算作一个节点,所以第一个li需要传递两个next_sibling才能得到下一个li节点。上一个也是如此。其实还有一种更简单的方法可以避免这些换行符被计算在内,就是在获取网页源代码的时候,简单的去掉换行符和空格即可。

  方法选择器

  对于节点选择器,博主介绍过可以用更少的文本内容来完成。但是,爬虫实际抓取到的url数据量很大,不适合开始使用节点选择器。所以,我们不得不考虑通过方法选择器进行处理的第一步。

  find_all() 方法

  find_all()方法主要用于根据节点名称、属性、文本内容等选择所有满足要求的节点,其完整定义如下:

  def find_all(self, name=None, attrs={}, recursive=True, text=None,

limit=None, **kwargs):

  范围

  意义

  姓名

  指定节点名称

  属性

  指定属性名和值,比如找到value="text"的节点,attrs={"value":"text"}

  递归的

  Boolean 类型,值为 True 查找后代节点,值为 False 为直接子节点,默认为 True

  文本

  指定要查找的文本

  限制

  因为find_all返回的是一个列表,可以长也可以短,limit类似于数据库语法,限制了获取的次数。不设置全部返回

  【实战】还是测试上面的HTML,我们得到name=a,attr={"class":"aaa"},文本等于text="Python section" section的节点。

  示例代码如下所示:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html.strip(), 'lxml')

a_list = soup.find_all(name='a', attrs={"class": 'aaa'}, text='Python板块')

for a in a_list:

print(a)

  运行后效果如下:

  

  查找()方法

  find() 和 find_all() 的区别只有一个 all,但结果有 2 点不同:

  1.find() 只查找第一个满足条件的节点,而 find_all() 查找所有满足条件的节点 2.find() 方法返回 bs4.element.Tag 对象,并且 find_all() 返回一个 bs4.element.ResultSet 对象

  接下来,我们在上面的 HTML 中查找 a 标签,看看返回的结果有什么不同。示例如下:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html.strip(), 'lxml')

a_list = soup.find_all(name='a')

print("find_all()方法")

for a in a_list:

print(a)

print("find()方法")

a = soup.find(name='a')

print(a)

  运行后效果如下:

  

  CSS 选择器

  首先,我们来了解一下 CSS 选择器的规则:

  1..classname:选择样式名为classname的节点,即class属性值为classname的节点2.#idname:选择id属性为idname的节点3.nodename :用nodename选择节点名node

  一般来说,在 BeautifulSoup 库中,我们使用函数 select() 来操作 CSS 选择器。一个例子如下:

  from bs4 import BeautifulSoup

with open('demo.html', 'r', encoding='utf-8') as f:

html = f.read()

soup = BeautifulSoup(html.strip(), 'lxml')

li = soup.select('.li1')

print(li)

  在这里,我们选择类等于 li1 的节点。运行后效果如下:

  

  嵌套选择节点

  因为,我们需要实现嵌套 CSS 选择器的使用,但是上面的 HTML 并不适合。在这里,我们稍作修改,改一下

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线