目录
1. 什么是Beautiful Soup
?2.?安装与使用
3.解析器的分类
3.2、NavigableString 获取标签的内容
3.3、Beautifulsoup
?3.5 CSS选择器
4.BeautifulSoup应用实例演示(爬豆瓣)
(1)将爬取的页面html信息以text的形式打印:
?(2)利用Beautifusoup解析页面:
?(3)取出每个子盒子
(4.1)取出每个子盒子里的网络链接?
?(4.2) 取出每个子盒子里的文本信息
5. 分页爬取豆瓣案例
?
1. 什么是Beautiful Soup
简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:
Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
Beautiful Soup已成为和lxml一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。
https://www.lfd.uci.edu/~gohlke/pythonlibs/? python二进制非官方包
下载对应的lxml解释器:
python3.7对应如下,下载后将其放入python的包中,进行安装:
也可以再terminal下运行:
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple?
pip install 名字.whl?
pip install?bs4?-i https://pypi.tuna.tsinghua.edu.cn/simple?
(虚拟环境需要到venv的安装目录下安装)
?2.?安装与使用
1、安装pip install?bs4
2、使用
首先必须要导入 bs4 库, 创建BeautifulSoup对象
from bs4 import BeautifulSoup as BS
Requests 结合使用
from bs4 import BeautifulSoup as BS
text = '''
<html>
<head>
<meta = charset='UTF-8' >
<title id =1 href = 'http://example.com/elsie' class = 'title'>Test</title>
</head>
<body>
<div class = 'ok'>
<div class = 'nice'>
<p class = 'p'>
Hello World
</p>
<p class = 'e'>
风一般的男人
</p>
</div>
</div>
</body>
</html>
'''
soup = BS(text, 'html.parser') # 解析器
print(type(soup))
print(soup.title) # 获取title标签
print(soup.title.name) # 获取标签的名字
print(soup.title.text) # 获取文本text
print(soup.title.attrs) # 获取属性字典
print(soup.title.string) # 获取文本text
print(soup.div.p.text.lstrip()) # 第一获取标签的文本(这打印的是第一个p标签)
"""
D:\Anaconda3\python.exe D:/Python_file_forAnconda3_python/爬虫/BeautifulSoup_01.py
<class 'bs4.BeautifulSoup'>
<title class="title" href="http://example.com/elsie" id="1">Test</title>
title
Test
{'id': '1', 'href': 'http://example.com/elsie', 'class': ['title']}
Test
Hello World
Process finished with exit code 0
"""
分析:?
(1) soup = BS(text, 'html.parser') ?# 解析器,其中将整个html文件作为text的内容,可见,Beautiful Soup对html起到了解析的作用。
(2)对于如上html中,假如要打印出"风一般的男子",则代码为:
soup = BS(text, 'html.parser') # 解析器
print(soup.find('p',class_='e').text.lstrip()) #lstrip()是去左边空格
(3)print(soup.find_all('p',class_='e')) 返回一个列表,
soup = BS(text, 'html.parser') # 解析器
print(soup.find_all('p',class_='e'))
"""
[<p class="e">
风一般的男人
</p>]
"""
打印:
soup = BS(text, 'html.parser') # 解析器
#print(soup.find_all('p',class_='e'))
result = soup.find_all('p',class_='e')
for i in result:
print(i.text.strip())
"""
D:\Anaconda3\python.exe D:/Python_file_forAnconda3_python/爬虫/BeautifulSoup_01.py
风一般的男人
"""
(4)select()方法
print(soup.select('.p')[-1].text.lstrip())
print(soup.select('.p')[0].text.lstrip())
"""
D:\Anaconda3\python.exe D:/Python_file_forAnconda3_python/爬虫/BeautifulSoup_01.py
Hello World
Hello World
"""
3.解析器的分类
什么是网页解析器,简单的说就是用来解析html网页的工具,准确的说:它是一个HTML网页信息提取工具,就是从html网页中解析提取出“我们需要的有价值的数据”或者“新的URL链接”的工具。
解析器 | 使用方法 | 优势 | 劣势 | Python标准库 | BeautifulSoup(markup, “html.parser”) | Python的内置标准库 执行速度适中 文档容错能力强 | (Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差 | lxml HTML 解析器 | BeautifulSoup(markup, “lxml”) | 速度快 文档容错能力强 | 需要安装C语言库 | lxml XML 解析器 | BeautifulSoup(markup, [“lxml”, “xml”]) BeautifulSoup(markup, “xml”) | 速度快 唯一支持XML的解析器 | 需要安装C语言库 | html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容错性 以浏览器的方式解析文档 生成HTML5格式的文档 | 速度慢 不依 |
Tag 就是Html中的标签,包含name和attrs
我们可以利用 soup加标签名轻松地获取这些标签的内容,是不是感觉比正则表达式方便多了?不过有一点是,它查找的是在所有内容中的第一个符合要求的标签,如果要查询所有的标签,我们在后面进行介绍。
#获取title标签
print(soup.title)
#获取标签的名字
print(soup.title.name)
#获取标签的内容
print(soup.title.text)
#获取标签的属性
print(soup.title.attrs)
#指定标签的某个属性
print(soup.title.get('class'))
?
3.2、NavigableString 获取标签的内容
#获取title标签中的内容
print(soup.title.string)
#获取p标签中的内容
print(soup.p.string)
3.3、Beautifulsoup
BeautifulSoup?对象表示的是一个文档的全部内容.大部分时候,可以把它当作?Tag?对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性。
Comment?对象是一个特殊类型的?NavigableString?对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦。所以要先进行判断是否是注释,再输出。
?3.5 CSS选择器
我们在写 CSS 时,标签名不加任何修饰,类名前加点,id名前加 #,在这里我们也可以利用类似的方法来筛选元素,用到的方法是?soup.select(),返回类型是list。
4.BeautifulSoup应用实例演示(爬豆瓣)
(1)将爬取的页面html信息以text的形式打印:
from bs4 import BeautifulSoup as BS
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
res = requests.get(url='https://movie.douban.com/cinema/later/haerbin/',headers=headers)
print(res.text)
?(2)利用Beautifusoup解析页面:
from bs4 import BeautifulSoup as BS
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
#返回页面信息
res = requests.get(url='https://movie.douban.com/cinema/later/haerbin/',headers=headers)
#print(res.text)
#解析页面
soup = BS(res.text,'html.parser')
box = soup.find('div',id='showing-soon') #获取总盒子(如图1)
items = box.find_all('div',class_='item mod ') #获取总盒子里的子盒子(如图2)(注:find_all()返回的是列表)
for i in items:
print("*"*100) #每打印一个盒子则打印“***”作为分割
print(i)
图1:
图2:
?
?(3)取出每个子盒子
for i in items:
print("*"*100) #每打印一个盒子则打印“***”作为分割
print(i.find('div',class_='intro')) #取出每一个子盒子(如图3)
?图3:
(4.1)取出每个子盒子里的网络链接?
代码如下:?
for i in items:
print("*"*100) #每打印一个盒子则打印“***”作为分割
#print(i.find('div',class_='intro')) #取出每一个子盒子(如图3)
print(i.find('div', class_='intro').a.attrs['href'])
?(4.2) 取出每个子盒子里的文本信息
for i in items:
print("-"*10)
#print(i.find('div',class_='intro')) #取出每一个子盒子(如图3)
print(i.find('div', class_='intro').a.text) #读取a标签下的文本
#print(i.find('div',class_='intro').a.attrs["href"]) #读取a标签下的链接信息
print(i.find('div', class_='intro').ul.text) # 读取ul列表下的文本信息
如下代码也可实现上述结果:?
for i in items:
print("-"*10)
print(i.find("div",class_='intro').get_text()) #get_text() 获取所有文本
5. 分页爬取豆瓣案例
import requests
from bs4 import BeautifulSoup as BS
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62'
}
def pa(movieId,page):
with open('a.txt','w',encoding='utf-8') as f: # 打开一个文件,以便将爬取的信息写入
for i in range(page): #page就是你要爬取的页数
print('正在爬取第%d页'% (i+1,))
url = 'https://movie.douban.com/subject/%d/comments?start=%d&limit=20&sort=new_score&status=P' % (movieId,i*20)
print(url)
res=requests.get(url=url,headers=headers) # 每一页都进行一次伪装,拿到页面数据
soup=BS(res.text,'html.parser').body #进行页面解析
f.write(soup.get_text()) #将解析到的信息写入文件a.txt
boxes = soup.find_all('div',class_='comment-item') #找到要爬信息所在的总盒子
for box in boxes: #打印子盒子中的信息
print("*"*50)
try:
print(box.find('span',class_='rating').attrs['class'][0].split('star')[1])
f.write(box.find('span',class_='short').text+'\n') #写入文件a.txt
except:
pass
pa(27010768,3)
|