爬虫(三)-- Beautiful Soup 4 库的实用详解

01 前言

经过前两篇的学习,现在手感正火热吧。
爬虫(一) – 带你了解爬虫最基本概念,一文即可实践
爬虫(二)–正则表达式
想要使用好爬虫,就需要很好的解析你所找到的代码,使用Beautiful Soup 4,俗称BS4,可以轻松实现。

官方文档:https://beautifulsoup.readthedocs.io/zh_CN/latest/

02 BeautifulSoup库

2.1 概念及整体输出

BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库,一个分析HTML或XML文件的解析器。通常用来分析网页结构,抓取相应的Web文档。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,"html.parser")
print(soup.prettify())

soup.prettify()将soup内容格式化输出,用BeautifulSoup 解析HTML文档时,它会将HTML文档类似DOM文档树一样处理。

注意:假设HTML源码标签对是缺少结束标签的,即没有和标签,但是使用prettify()函数输出的结果可以自动补齐结束标签,这是BeautifulSoup的一个优点:BeautifulSoup即使得到了一个损坏的标签,它也产生一个转换DOM树,并尽可能和您原文档内容含义一致,这种措施通常能够帮助您更正确地搜集数据。

2.2 BeautifulSoup对象

BeautifulSoup官方文档将所有的对象归纳为以下四种:

  • Tag :包括Name和Attributes,
#Name
print(tag.name)   # 输出标签名
print(tag.string)  # 输出标签的内容

#Attributes
print(tag.attrs) # 以键值对的方式输出标签的class和id
print(tag['class'])  # 得到class的值

获得最初始的标签内容:

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,"html.parser")

# 获取HTML的标题,包括自身标签全部输出
head = soup.head
print('头部:', head)

# 头部: <head><title>BeautifulSoup技术</title></head>

注意,这种直接.head的方式只能获得对应的第一个标签,想要获得所有的标签内容,还是需要后续学到的finid_all()函数。

  • NavigableString
    实例:soup.a[‘class’].string,获得第一个遍历到的,具有class类的超链接标签内容
  • BeautifulSoup
    BeautifulSoup对象表示的是一个文档的全部内容。
print(type(soup))
# <class 'BeautifulSoup.BeautifulSoup'>
  • Comment
    Comment对象是一个特殊类型的NavigableString对象,它用于处理注释对象。

实例:

markup = "<b><!-- This is a comment code. --></b>"  
soup = BeautifulSoup(markup, "html.parser")
comment = soup.b.string 
print(comment) 

2.3 得到html标签里面的内容的方法

1、已知想要获得的信息的具体位置,只得到一个内容

soup = BeautifulSoup(html)
# 方法一:获得第二个a标签下的内容,已知标签所在位置
print(soup.select('a')[1].string)
# 方法二,已知标签所在位置
print(soup.find('a').contents[1])

2、位置信息未知,只得到一个内容

# 或者,未知标签所在位置,只知道你要找的class,再利用正则表达式提取文字
dufu_text = soup.find('a', {
    
    'class': 'poet1'}).text
dufu_two_chars = re.search(r'(\S\S)', dufu_text).group(1)

print(dufu_two_chars) # 输出:杜甫的两个字“杜甫”

# 或者
dufu_text = soup.find('a', class_ = 'poet1')
print(dufu_text.text)

3、位置信息未知,得到所有内容

# 位置标签所在位置,使用find_all方法,必须使用列表遍历的方式输出
dufu_text = soup.find_all('a', class_ = 'poet1')

for dufu in dufu_text:
    print(dufu.text)

4、想要得到超链接标签下的url

links = soup.find_all('a',class_ = 'poet1')

# 按照列表的形式取出
for link in links:
    print(link.get('href'))

# 或者如下
for index, link in enumerate(links1):
    href = link['href']
    print(f"Index: {
      
      index}, Href: {
      
      href}")

2.4 最便捷语句find_all()详解

  find_all()函数是BeautifulSoup库中用于查找文档中所有符合条件的元素的函数。它可以接受多个参数,用于指定要搜索的元素的特定属性和属性值。下面是find_all()函数的参数详解:

  • name参数:指定要搜索的标签名称或标签列表。可以是字符串或正则表达式对象。如果不指定此参数,则返回文档中的所有标签。

正则表达式:find_all(re.compile(“正则表达式”))

  • attrs参数:指定要搜索的元素的属性和属性值。可以是字典类型或关键字参数。字典类型的键是属性名,值是属性值。如果关键字参数用于传递属性和属性值,则属性名称作为关键字,属性值作为值。

dufu_text = soup.find_all(‘a’, attrs = {‘class’: ‘poet1’})

  • recursive参数:指定是否在文档的子孙节点中递归搜索。默认值为True,表示递归搜索。如果设置为False,则只搜索文档的直接子节点。

  • string参数:指定要搜索的元素的文本内容。可以是字符串或正则表达式对象。如果指定此参数,则只返回包含指定文本的元素。

soup.find_all(string=[“Tillie”, “Elsie”, “Lacie”])

  • limit参数:指定返回的结果数量的限制。默认值为None,表示返回所有结果。如果设置了限制,则返回最多指定数量的结果。

  • **kwargs参数:用于传递其他参数,例如CSS选择器等,例如:

soup.find_all(“a”, class_=“poet”,id=‘link1’)

2.5 遍历文档树

参考了下列文档:
1、https://blog.csdn.net/Eastmount/article/details/109497225

2、https://blog.csdn.net/qq_42554007/article/details/90675142?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168005957816800186557025%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=168005957816800186557025&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~hot_rank-5-90675142-null-null.142v76insert_down38,201v4add_ask,239v2insert_chatgpt&utm_term=beautifulsoup&spm=1018.2226.3001.4187

3、https://blog.csdn.net/xuebiaojun/article/details/119654841?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168009930316800192237083%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=168009930316800192237083&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-1-119654841-null-null.142v77insert_down38,201v4add_ask,239v2insert_chatgpt&utm_term=soup.find_all%E7%94%A8%E6%B3%95&spm=1018.2226.3001.4187

  • 获得第一个子节点:children或者contents

真正使用的时候,一般使用find_all,而不用这些节点,这些节点是为了让结构更清晰。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,"html.parser")
print(soup.head.contents)  # 输出hrad标签下的第一个子标签
for contents in soup.head.contents:
    print(contents)
  • 如果需要获取多个节点内容时,则使用strings属性:
for content in soup.head.strings:
    print(content)
  • 输出的字符串可能包含多余的空格或换行,这里需要使用stripped_strings方法去除多余的空白内容,代码如下:
for content in soup.stripped_strings:
    print(content)

其他文档树的节点,搜索文档树与遍历文档树类似,包括父节点、子节点、兄弟节点等,推荐从官网自行学习。一般来说都是使用find_all

03 BOM和DOM

为了学好使用BS4,很有必要了解BOM和DOM,原来想写在一起的,后来发现可能需要单独研究,本篇暂时就到这里结束啦,下一篇更新BOM和DOM,后续持续教你写爬虫~

猜你喜欢

转载自blog.csdn.net/qq_54015136/article/details/129843517