您当前的位置: 首页 >  Python

快乐很重要的汪

暂无认证

  • 2浏览

    0关注

    36博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Python爬虫实例(2)--beautifulsoup的应用

快乐很重要的汪 发布时间:2022-08-29 23:49:03 ,浏览量:2

系列文章目录

我们上一讲已经学习了request的用法。

现在我们需要来处理得到的HTML信息。 本章节我们使用BeautifulSoup。漂亮的汤

耗时约15min,建议实操。

使用的网站延续前一讲。

这一小节我们的任务是得到网站上的基础信息,比如作者等。

文章目录
  • 系列文章目录
  • 前言
  • 一、BeautifulSoup是什么?
  • 二、使用步骤
    • 1.使用HTML数据构建soup
    • 2.soup.find('tagName')
    • 3.soup.find_all()
  • 三、实操
    • 目标分析
    • 定位目标
    • 字符串提取
  • 四、总结

前言

HTML的本质还是文本。那么对于python而言就是字符串。

所以从网页中提取信息,就变成了从字符串中提取子字符串。

但是又有什么不同呢?

  1. HTML的文本并不是线性的,而是树形的(DOM树)。

  2. HTML有很多标签属性等,这些和目标信息强相关。

    所以提取子字符串有其特定的方法

一、BeautifulSoup是什么?

beautifulsoup4库,也称为Beautiful Soup库或者bs4库,用于解析和处理HTML和XML。 名字有那么点恶趣味,但是功能还是很强大的。

pip install beautifulsoup4
import bs4
print bs4
# 最经常
from bs4 import BeautifulSoup
二、使用步骤 1.使用HTML数据构建soup

代码如下(示例):

soup = BeautifulSoup(html_text, 'html.parser')
print(soup.p.string) # 第一段的字符串内容
# 作    者:圣骑士的传说

这里用.去索引信息,是比较简单的情形,所以有缩写。。。 但是真正主力的是接下来的两个工具。

2.soup.find(‘tagName’)
:param name: A filter on tag name. 一般就是tag
:param attrs: A dictionary of filters on attribute values. 用于限定的属性
:param recursive: If this is True, find() will perform a
    recursive search of this PageElement's children. Otherwise, only the direct children will be considered.
:param limit: Stop looking after finding this many results. :kwargs: A dictionary of filters on attribute values.
:return: A PageElement.
:rtype: bs4.element.Tag | bs4.element.NavigableString

注意: 1. find的返回结果也是soup类型,所以可以迭代,一步步逼近目标。 2. recursive默认是FALSE,防止抓取到过多的信息。除非没什么干扰项 3. find只会返回自上而下找到的第一个。

3.soup.find_all()

爬虫大部分情况是在信息比较丰富的网页上批量的爬取数据。 所以find有很大的局限性。这个时候就需要find_all

和上面的find基本一致,除了返回的是一个列表之外。。。 见下面实操。

三、实操

为了避免反复爬取所以我们保存到文件中。

html_text = rep.text.encode('iso-8859-1').decode('gbk')

with open("shouye.txt","w",encoding="gbk") as outfile:
    outfile.write(html_text)

with open("shouye.txt","r",encoding="gbk") as infile:
    html_text=infile.read()

在这里插入图片描述 然后注释掉爬取的部分。

目标分析
修真聊天群
作    者:圣骑士的传说
状    态:连载
动    作:直达底部  加入书架
最后更新:2020-08-10 11:24:43
最新章节:新书上传啦,《万界点名册》
定位目标
工具是有限的,但是组合是无限的

定位的目的是为了快速的实现唯一性。


	笔趣阁 > 修真聊天群最新章节
            	
                        
			
				修真聊天群
				作    者:圣骑士的传说
				状    态:连载
                                动    作:直达底部  加入书架
				最后更新:2020-08-10 11:24:43
				最新章节:新书上传啦,《万界点名册》

根据观察。我们id属性为book的div是唯一的。所以我们可以从这里开始。  代表空格键,转义了而已。

实际上可以更进一步从这里开始。甚至可以直接用id。但是为了展示一下层层递进的定位方式。。。 没有困难,就要创造困难!!! 在这里插入图片描述

print(soup.find("div",attrs={"id":"book"}).find("div",attrs={"id":"info"})) # 递进的写法
print(soup.find_all("div",attrs={"id":"info"})) # 直接的写法
# find_all的结果 find的结果没有列表!!!
[
修真聊天群
作    者:圣骑士的传说
状    态:连载
动    作:直达底部  加入书架
最后更新:2020-08-10 11:24:43
最新章节:新书上传啦,《万界点名册》
]
我想说的是find返回的还是soup可以一直在后面追加,就像从树的根节点到叶结点的过程。每一次find都相当于路径
显然这个路径是可以跳步的。只要思路好!!!

接下来更进一步!

字符串提取
如何将作者打印出来?

我们以作者为例

content = soup.find("div",attrs={"id":"book"}).find("div",attrs={"id":"info"}).find('p').string
print(content.split(":")) # 注意这个冒号
author = re.findall(r"作\xa0\xa0\xa0\xa0者:(.*)",content)[0]
print(author)
# 结果
['作\xa0\xa0\xa0\xa0者', '圣骑士的传说']
['圣骑士的传说']

还是很容易写错的。比如中间的空格符因为编码不一样所以可能匹配不到。 作 者,中间四个加空格就不行。 还有冒号也有中英文的区别。

\xa0 是不间断空白符   我们通常所用的空格是 \x20 ,是在标准ASCII可见字符 0x20~0x7e 范围内。 而 \xa0 属于 latin1 (ISO/IEC_8859-1)中的扩展字符集字符,代表空白符nbsp(non-breaking space)

' '.join(v.split())# 是用这个去转化然后处理,相当于换成了一般的空格。
四、总结

剩下的几个信息,大同小异,我相信留给诸位并不是很难。(用find_all)

还记得一开始,保存HTML到文件,然后用记事本打开吗?

用记事本打开的小伙伴基本是要翻车的。。。没错,我在误导你,就是这么邪恶。

记事本往往不会很好的显示格式或者空字符等等。但是这对我们定位信息是大忌。

推荐使用notepad++。 在这里插入图片描述 小而美的软件值得拥有。 链接:https://pan.baidu.com/s/19xovb6z086ycmbB_zc4siw 提取码:fmg5

仅仅这一个实例是不够的。 下一讲,是关于章节标题的爬取以及处理。

关注
打赏
1663165558
查看更多评论
立即登录/注册

微信扫码登录

0.0527s