爬虫解析-BeautifulSoup-bs4(七)

2023-12-09 07:44

本文主要是介绍爬虫解析-BeautifulSoup-bs4(七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.bs4的安装

2.bs4的语法

(1)查找节点

 (2)查找结点信息

3.bs4的操作

(1)对本地文件进行操作

(2)对服务器响应文件进行操作

4.实战


beautifulsoup:和lxml一样,是一个html的解析器,主要功能也是解析和提取数据。

优缺点

        缺点:没有lxml效率高

        优点:接口更加人性化,使用方便

1.bs4的安装

安装:pip install bs4

导入 from bs4 import BeautifulSoup

2.bs4的语法

(1)查找节点

1.根据标签名查找节点:

       soup.a 【注】只能找到第一个

              soup.a.name  标签a的名字,即“a”

              soup.a.attrs   标签a 的属性,即“href=”..”

2.函数

       (1).find(返回一个对象)

              find(‘a’):只找到第一个 a 标签

              find(‘a’, title=’属性值’)

              find(‘a’, class=’属性值’)

       (2).find_all (返回一个列表)

                find_all('a’) 查找到所有的a

                find_all(['a,'span']) 返回所有的a和span

                find_all('a",limit=2) 只找前两个a

        (3).select(根选择器得到节点对象)【推荐】

                1. element

                        eg:p

                2..class

                        eg: .firstname

                3.#id

                        eg:#firstname

                4.属性选择器

                        [attribute]

                5.层级选择器

                        ①后代选择器:element element

                                div p

                        ②子代选择器:element>element

                               div>p

                        ③多项选择器:element ,element

                                div,p

                                        eg:soup = soup.select("a,span')

# 根据标签名查找节点
# 注意:找到的是第一个符合条件的数据
print(soup.a)   # <a href="https://..." id="a1">BeautifulSoup</a>
# 获取标签名
print(soup.a.name)      # a
# 获取标签的属性和属性值
print(soup.a.attrs)     # {'href': 'https://...', 'id': 'a1'}# bs4 的一些函数
# (1)find 返回的是第一个符合条件的对象
print(soup.find('a')) # <a href="https://..." id="a1">BeautifulSoup</a>
# 根据属性值找到符合条件的标签对象
print(soup.find('a', id='a2'))     #<a href="http://..." id="a2">lxml</a>
# 根据class查找标签对象,注意,class要加下划线'class_',因为这里的的class和定义类的class冲突了
print(soup.find('a',class_='link'))# (2)findAll 返回的是所有符合条件的对象的列表
# 找到所有符合条件的标签对象
print(soup.findAll('a'))    # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>, <a href="http://..." id="a2">lxml</a>]
# 获取多个标签,需要在 findAll中添加列表的数据
print(soup.findAll(['a','span']))   # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>, <span>demo</span>, <a href="http://..." id="a2">lxml</a>]
# 找前几个符合条件的数据
print(soup.findAll('a',limit=1))# (3)select
# select 返回的是所有符合条件的对象列表
print(soup.select('a'))     # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>, <a href="http://..." id="a2">lxml</a>]
# 可以通过 '.' 代表 class,我们把这种操作叫做类选择器
print(soup.select('.link'))     # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>]
print(soup.select('#a1'))   # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>]# 属性选择器 通过属性来寻找对应的标签
# 查找<li>标签中有class的标签
print(soup.select('li[class]'))  # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>]
# 查找<li>标签中 id 为 l2 的标签
print(soup.select('li[id="l2"]'))   # [<li class="c2" id="l2">上海</li>]# 层级选择器
# 后代选择器
# 找到 div 下面的 li
print(soup.select('div li'))    # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>, <li id="s1">广州</li>, <li id="s2">深圳</li>]
# 子代选择器
# 某标签的第一级子标签
print(soup.select('div > ul > li'))     # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>, <li id="s1">广州</li>, <li id="s2">深圳</li>]
# 找到 a 标签 和 li 标签的所有对象
print(soup.select('a, li'))     # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>, <li id="s1">广州</li>, <li id="s2">深圳</li>, <a class="link" href="https://..." id="a1">BeautifulSoup</a>, <a href="http://..." id="a2">lxml</a>]

 (2)查找结点信息

1.获取节点内容: 适用于标签中嵌套标签的结构

        obj.string

        obj.get_text()[推荐]

2.节点的属性

        tag.name 获取标签名

                eg:tag=find("li)

                print(tag.name)

        tag.attrs将属性值作为一个字典返回

3.获取节点属性

        obj.attrs.get('title')[常用]

        obj.get('title')

        obj['title"]

# 节点信息
# 获取节点内容
obj = soup.select('#d2')
# 如果 标签对象中只有内容,那string和get_text(),如果标签对象中,除了内容还有标签,那string就获取不到数据,而get_text()可以获取到数据
# 推荐使用 get_text()
print(obj[0].string)
print(obj[0].get_text())# 节点的属性
# 标签的名字
obj = soup.select('#p1')
print(obj[0].name)       # p
# 将属性值作为一个字典返回
print(obj[0].attrs)     # {'id': 'p1', 'class': ['p1']}# 获取节点的属性
obj = soup.select('#p1')[0]
print(obj.attrs.get('class'))   # ['p1']
print(obj.get('class'))   # ['p1']
print(obj['class'])   # ['p1']

HTML文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"/><title>Title</title>
</head>
<body><div><ul><li id='l1' class="c1">北京</li><li id="l2" class="c2">上海</li><li id="s1">广州</li><li id="s2">深圳</li><a href="https://..." id="a1" class="link">BeautifulSoup</a><span>demo</span></ul></div><a href="http://..." id="a2">lxml</a><div id = 'd2'><span>temp</span></div><p id="p1" class="p1">id和class都是p1怎么办</p>
</body>
</html>

3.bs4的操作

bs4可以对服务器响应文件和本地文件进行操作

(1)服务器响应的文件生成对象

soup = BeautifulSoup(response.read().decode(),’lxml’)

(2)本地文件生成对象

soup = BeautifulSoup(open(‘1.html’),’lxml’

(1)对本地文件进行操作

from bs4 import BeautifulSoup# 通过解析本地文件讲解bs4 的基本语法
soup = BeautifulSoup(open('_075.html','r',encoding='utf-8'),'lxml')

(2)对服务器响应文件进行操作

import urllib.requesturl = 'https://www.starbucks.com.cn/menu/'request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')from bs4 import BeautifulSoup
# 通过解析本地文件讲解bs4 的基本语法
soup = BeautifulSoup(content,'lxml')

4.实战

获取豆瓣评分的 Top250。

from bs4 import BeautifulSoup
import requests# 小demo
# content = requests.get("http://books.toscrape.com/").text
# # html.parser 指定解析器,说明我们正在解析html内容
# soup = BeautifulSoup(content,"html.parser")# # findAll返回一个可迭代对象
# # 通过特有class查找元素
# all_price = soup.findAll("p",attrs={"class": "price_color"})
# # print(all_price)
# for i in all_price:
#     # 只想要数字,不想要标签,调用string属性
#     print(i.string)# # 根据共有标签查找元素
# all_title = soup.findAll("h3")
# for i in all_title:
#     all_a = soup.findAll("a")
#     # # 如果该标签下只有一个<a>元素,那就直接用find提取这个元素就ok了,这样就能少写一个循环
#     # a = soup.find("a")
#     for link in all_a:
#         print(link.string)headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.76"
}for start_num in range(0,250,25):response = requests.get(f'https://movie.douban.com/top250?start={start_num}', headers = headers)html = response.textsoup = BeautifulSoup(html,"html.parser")all_title = soup.findAll("span",attrs={"class":"title"})for title in all_title:title_string = title.stringif "/" not in title_string:print(title_string)

参考

尚硅谷Python爬虫教程小白零基础速通(含python基础+爬虫案例)

这篇关于爬虫解析-BeautifulSoup-bs4(七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/473008

相关文章

C++ 右值引用(rvalue references)与移动语义(move semantics)深度解析

《C++右值引用(rvaluereferences)与移动语义(movesemantics)深度解析》文章主要介绍了C++右值引用和移动语义的设计动机、基本概念、实现方式以及在实际编程中的应用,... 目录一、右值引用(rvalue references)与移动语义(move semantics)设计动机1

MySQL 筛选条件放 ON后 vs 放 WHERE 后的区别解析

《MySQL筛选条件放ON后vs放WHERE后的区别解析》文章解释了在MySQL中,将筛选条件放在ON和WHERE中的区别,文章通过几个场景说明了ON和WHERE的区别,并总结了ON用于关... 今天我们来讲讲数据库筛选条件放 ON 后和放 WHERE 后的区别。ON 决定如何 "连接" 表,WHERE

Mybatis的mapper文件中#和$的区别示例解析

《Mybatis的mapper文件中#和$的区别示例解析》MyBatis的mapper文件中,#{}和${}是两种参数占位符,核心差异在于参数解析方式、SQL注入风险、适用场景,以下从底层原理、使用场... 目录MyBATis 中 mapper 文件里 #{} 与 ${} 的核心区别一、核心区别对比表二、底

Agent开发核心技术解析以及现代Agent架构设计

《Agent开发核心技术解析以及现代Agent架构设计》在人工智能领域,Agent并非一个全新的概念,但在大模型时代,它被赋予了全新的生命力,简单来说,Agent是一个能够自主感知环境、理解任务、制定... 目录一、回归本源:到底什么是Agent?二、核心链路拆解:Agent的"大脑"与"四肢"1. 规划模

MySQL字符串转数值的方法全解析

《MySQL字符串转数值的方法全解析》在MySQL开发中,字符串与数值的转换是高频操作,本文从隐式转换原理、显式转换方法、典型场景案例、风险防控四个维度系统梳理,助您精准掌握这一核心技能,需要的朋友可... 目录一、隐式转换:自动但需警惕的&ld编程quo;双刃剑”二、显式转换:三大核心方法详解三、典型场景

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro

Python多任务爬虫实现爬取图片和GDP数据

《Python多任务爬虫实现爬取图片和GDP数据》本文主要介绍了基于FastAPI开发Web站点的方法,包括搭建Web服务器、处理图片资源、实现多任务爬虫和数据可视化,同时,还简要介绍了Python爬... 目录一. 基于FastAPI之Web站点开发1. 基于FastAPI搭建Web服务器2. Web服务

C++ 多态性实战之何时使用 virtual 和 override的问题解析

《C++多态性实战之何时使用virtual和override的问题解析》在面向对象编程中,多态是一个核心概念,很多开发者在遇到override编译错误时,不清楚是否需要将基类函数声明为virt... 目录C++ 多态性实战:何时使用 virtual 和 override?引言问题场景判断是否需要多态的三个关

Springboot主配置文件解析

《Springboot主配置文件解析》SpringBoot主配置文件application.yml支持多种核心值类型,包括字符串、数字、布尔值等,文章详细介绍了Profile环境配置和加载位置,本文... 目录Profile环境配置配置文件加载位置Springboot主配置文件 application.ym

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、