BeautifulSoup4、数据持久化
day13
01-BeautifulSoup4概述
1.BeautifulSoup4概述
BeautifulSoup是一个用于从HTML文件中提取数据的模块,使用BeautifulSoup模块,你就可以从HTML中提取到你想要的任何数据,BeautifulSoup4是BeautifulSoup系列模块的第四代
2.BeautifulSoup4模块的安装
Windows:pip install BeautifulSoup4
Mac、Linux:pip3 install BeautifulSoup4
3.使用
from bs4 import BeautifulSoup
# 假设html_str就是requests拿到的字符串类型的网页源代码
html_str = """
<html>
<head><title>The Dormouse's story</title></head>
<body>
<p class="title">
<b>The Dormouse"s story</ b>
</p>
<p class="story" id="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie<p>Test</p></a>;
and they lived at the bottom of a well.
</p>
<p class="story" id="story">...</p>
"""
# 使用BeautifulSoup方法针对于网页源代码进行文档解析,返回一个BeautifulSoup对象(树结构)
# html.parser? 解析过程需要解析器,html.parser是一个解析器
soup = BeautifulSoup(html_str, 'html.parser')
# Q1:从soup这个树结构中提取所有的p标签
# 标签选择器:只写标签名,能从树结构中拿到所有的某个标签
p_list = soup.select('p')
print(p_list)
print('----------')
# Q2:提取body标签下的所有p子标签
# 父子选择器:> 右边的是子标签,左边的是父标签
# body > p从整个树结构soup中找到body标签,再去找body的p子标签
p_list1 = soup.select('body > p')
print(p_list1)
print('----------')
# CSS选择器的作用:按照树结构,寻找所需要的内容(限定条件)
# Q3:提取body标签下的所有p标签
# 后代选择器:祖先标签和后代标签使用空格隔开,祖先在左,后代在右
# 注意:父子关系一定是后代关系,后代关系不一定是父子关系
p_list2 = soup.select('body p')
print(p_list2)
print('----------')
# Q4:提取body标签下的第一个p子标签
# class选择器,class属性对应的属性值使用点.调用
p_list3 = soup.select('body > p.title')
print(p_list3)
print('----------')
# Q5:提取body标签的后两个子标签
# id选择器:id属性名对应的属性值使用#调用
p_list4 = soup.select('body > p#story')
print(p_list4)
print('----------')
# Q6:提取body标签下的第二个p子标签的第三个a子标签的标签内容和href属性值
# nth-child选择器:不区别标签名,获取同级所有标签的第N个
p_list5 = soup.select('body > p:nth-child(2) > a:nth-child(3)')[0].text
print(p_list5)
p_list6 = soup.select('body > p:nth-child(2) > a:nth-child(3)')[0].attrs['href']
print(p_list6)
# 所有CSS选择器能够随意组合使用
从网页中提取内容的方法和属性
1.select:使用CSS选择器(标签选择器、id选择器、class选择器、父子选择器、后代选择器、nth-child选择器等)
从树结构中遍历符合得结果,存放在列表中,列表中的每个元素依旧是树结构
2.select_one:使用CSS选择器(标签选择器、id选择器、class选择器、父子选择器、后代选择器、nth-child选择器等)
从树结构中拿到符合条件的第一个结果,这个结果依旧是树结构(返回类型不是列表,是一个元素)
3.text:从树结构中得到标签中的内容,结果为字符串
4.attrs:从树结构的标签中获得属性名对应的属性值,结果为字符串
day14
01-中国新闻网爬虫
直接上完全体,多页爬取和进度条在后面解释,主要是对bs4的简单应用
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
# 中国新闻网即时新闻精选链接
for page in tqdm(range(1, 11), desc='中国新闻网爬虫'):
# print(f'----------------第{page}页-----------------')
URL = f'https://www.chinanews.com.cn/scroll-news/news{page}.html'
# 伪装爬虫,获取User-Agent
Headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.34'
}
# 向网站所在服务器发送请求,拿到相应结果
response = requests.get(url=URL, headers=Headers)
response.encoding = 'utf-8'
# 判断状态码是否为200
result = response.text if response.status_code == 200 else response.status_code
# print(result)
# 使用bs4模块将网页源代码转为树结构
soup = BeautifulSoup(response.text, 'html.parser')
# 按照网页结构(树结构)从外到内查询、提取数据
# 先提取出所有新闻所在的li标签
lilist = soup.select('html > body > div.w1280.mt20 div.content_list > ul > li')
# print(lilist)
# 获取新闻详情
for i in lilist:
# 去除空的li标签
if i.select('li > div.dd_lm > a') != []:
# 新闻类型
newsType = i.select_one('li > div.dd_lm > a').text
# 新闻标题
newsTitle = i.select_one('li > div.dd_bt > a').text
# 新闻详情页链接
newsLink = 'https://www.chinanews.com.cn/' + i.select_one('li > div.dd_bt > a').attrs['href']
# 发布时间
newsTime = i.select_one('li > div.dd_time').text
# print(newsType, newsTitle, newsLink, newsTime)
02-多页爬取
对整个爬取的过程套一个for循环,range里面写好页数
for page in range(1, 11):
URL = f'https://www.chinanews.com.cn/scroll-news/news{page}.html'
03-爬虫添加进度条
Python的进度条模块之一:tqdm
1.安装:pip install tqdm
2.使用:有进度条没有print,有print没有进度条,实现数据持久化之后就不需要再打印了,可以直接省去print添加tqdm进度条
from tqdm import tqdm
# tqdm操作的对象也是容器
for i in tqdm(range(1, 100000001), desc='这是一个小小的进度条'):
# 保证结构的完整性,不参与程序的执行
pass
day15
01-豆瓣电影Top250作业
还是直接上完全体,其他内容的说明放到后面,这次操作内容包括bs4,数据持久化,还有对前面内容的复习,真要三思而后行,昨天多次试错,ip直接进黑名单了,差点提前预习代理池了
import requests
import time
from random import randint
from bs4 import BeautifulSoup
from tqdm import tqdm
# 创建文本文件
file = open('豆瓣电影Top250.txt', 'wt', encoding='utf-8')
file.write('电影标题,电影评分,评论人数,中心思想\n')
for i in tqdm(range(0, 10), desc='豆瓣电影Top250爬虫'):
# print(f'---------这是第{i + 1}页----------')
URL = f'https://movie.douban.com/top250?start={i * 25}&filter='
Headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.34'
}
response = requests.get(url=URL, headers=Headers)
# print(response.text)
# result = '正常' if response.status_code == 200 else response.status_code
# print(result)
soup = BeautifulSoup(response.text, 'html.parser')
lilist = soup.select('html > body > div#wrapper ol > li')
# print(lilist)
for i in lilist:
# 电影标题
movieTitle = i.select('li > div.item > div.info > div.hd > a > span.title')
movieList = [i.text for i in movieTitle]
movieTitle = ''.join(movieList).replace(' ', ' ')
# 电影评分
movieScore = i.select_one('li div.bd > div.star > span.rating_num').text
# # 电影评论人数
commPeople = i.select_one('li div.bd > div.star > span:nth-child(4)').text
# 中心思想
middIdea = i.select_one('li div.bd > p.quote > span.inq')
middIdea = middIdea.text if middIdea != None else ''
# print(movieTitle, movieScore, commPeople, middIdea)
data = [movieTitle, movieScore, commPeople, middIdea, '\n']
# 写入数据
file.write(','.join(data))
# 每一页爬取完毕,休眠一下,防止我们被检测到
# sleep:休眠,强制等待几秒钟
time.sleep(randint(1, 3))
file.close()
print('写入完成,文件已关闭')
02-数据持久化
一、为什么要数据持久化?
持久化将程序数据在持久状态和瞬时状态间转换的机制将瞬时状态(内存中的数据,是不能永久保存的)转换为持久数据(硬盘中的数据,能够长久保存),持久化的应用是将内存中的对象存储在硬盘、数据库等位置
二、可以将数据写到哪些位置?
1.照片中、音频、视频中
2.表格文件中、压缩包中
3.文本文件中
4.数据库中等等
03-文本文件的读写模式
一、使用python打开一个文件:open方法
open(参数1,参数2,参数3…)
首先讲讲最重要的参数2
1.文件打开后能做什么
w: 只写,先清空文件,再写入内容,如果文件不存在,先创建,再写入
a: 只写,直接在文件末尾追加写,如果文件不存在,也是先创建再写入
r: 只读,如果文件不存在,报错
2.打开文件以后操作文件的数据类型
t: 读写的数据类型必须是文本(text)
b: 读写的数据类型必须是二进制(bytes)
上述两组模式各选其一组合使用,例如: wt、tw、at、ta、rt、tr等等
二进制文件(图片、音频、视频等)必须以b模式打开,文本文件等要以t模式打开
04-文本文件的写操作
一、你在操作文件时,你的文件操作顺序?
例如:读某一个文件:打开文件 -> 查看文件内容 -> 关闭文件
例如:向新文件中写入数据:新建文件 -> 重命名 -> 写入内容 -> 保存关闭
二、open方法的使用
open方法用于打开一个文件并返回被打开的这个文件对象,open(参数1, 参数2, 参数3…)
1.参数1:file --> 文件的路径以及文件名(文件路径分为相对路径和绝对路径,编程中仅仅使用相对路径)
绝对路径:以盘符为参照物,对盘符来说文件的位置;相对路径:以某个文件为参照物,另一个文件的位置
2.参数3:编码方式 -> encoding:一般将encoding写为utf-8,但是有些文件编码不是utf-8,而是gbk等编码
三、文本文件写操作
# 1.打开一个文件,如果文件不存在,创建
file = open('./古诗.txt', 'wt', encoding='utf-8')
# 2.向打开的文件中写入内容
str_1 = '静夜思\n唐 李白\n床前明月光, \n疑是地上霜, \n举头望明月, \n低头思故乡。\n'
file.write(str_1)
# 3.关闭文件
file.close()
文件关闭之后就不能再进行I/O操作(input/out)
05-文本文件的读操作
# 1.打开文件
# 读写同一个文件的编码方式需要保持一致
file = open('豆瓣电影Top250.txt', 'rt', encoding='utf-8')
# 2.读取数据
# readline():每次只读取一行数据,字符串类型
data_1 = file.readline()
data_2 = file.readline()
print(data_1, data_2)
# read方法:能够将文件中的数据一次性全部读取出来
# read会接着readline读
data_3 = file.read()
print(data_3)
# readlines():一次性将所有的行读出来,每一行作为一个元素保存在列表中
data_4 = file.readlines()
print(data_4)
# 3.关闭文件
file.close()
06-二进制数据的读写
电脑中所有的文件都是以二进制数据保存的,有些文件,例如word、ppt、txt、pdf这些文件,里面保存的信息是供人阅读的,人接受的是文本、十进制等,所以这些信息是经过计算机处理的。
file = open('CU5QJM}M)HL7}CZE_%QP822.jpg', 'rb')
data = file.read()
# print(data)
file.close()
# 二进制数据标志:b''
file1 = open('图片.jpg', 'wb')
file1.write(data)
file1.close()
总结:t模式操作的是文件内容,b模式操作的是文件本身
07-图片视频等文件的下载
比较简单不多说,直接上代码
import requests
URL = 'https://img.paulzzh.com/touhou/konachan/image/b5b95f564c282d482dde8c4fc22c1b67.jpg'
response = requests.get(url=URL)
print(response.status_code)
# 拿到响应结果中源代码的的二进制形式:content
# print(response.content)
file = open('图片1.jpg', 'wb')
file.write(response.content)
file.close()
URL = 'https://video.pearvideo.com/mp4/adshort/20200817/cont-1689851-15331918_adpkg-ad_hd.mp4'
response = requests.get(url=URL)
video = open('视频.mp4', 'wb')
video.write(response.content)
video.close()
# 抖音链接就是要长一点哈
URL = 'https://v26-web.douyinvod.com/3e842f317b530670940cbfdfbb5a3e4e/6436aa34/video/tos/cn/tos-cn-ve-15c001-alinc2/oQ8IAHo6hfA9TCQgUe5zChngChYB7EyQQAvtBg/?a=6383&ch=5&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=1180&bt=1180&cs=0&ds=3&ft=GN7rKGVVywfURsm80mo~xj7ScoApc~es6vrKXgWdc2o0g3&mime_type=video_mp4&qs=0&rc=ODtlZDg6PDVnZTRoPDM3NUBpMzR4dTc6Zmo4ajMzNGkzM0AzLV40NTExNmIxXy8tXmBjYSNxLnBycjRvbzVgLS1kLS9zcw%3D%3D&l=202304121955082EB82230971CB0119CD4&btag=8000'
response = requests.get(url=URL)
video = open('视频1.mp4', 'wb')
video.write(response.content)
video.close()
08-csv文件的写操作
# 1.导入csv模块
import csv
# 2.以utf-8编码和写模式创建或打开'学生成绩.csv'文件
# wt/rt/at,涉及到文本类型的读写时,t可以忽略不写
f = open('学生成绩.csv', 'wt', encoding='utf-8', newline='')
# newline:以什么样的形式切换到下一行
# 将newline改为'',是因为windows的换行定义的是\r\n,mac定义的换行操作为\r,linux定义的换行操作为\n
# 统一将newline改为'',抵消掉不同系统产生的换行印象
# 3.使用csv模块中的writer类对文件对象进行写操作,返回一个具有写功能的writer对象
file_write = csv.writer(f)
# 4.写入数据
# 表格文件分为标题和对应的内容
# writerow:单行写入,将一个列表看作一行数据,列表中的每个元素对应这一行的单元格
# writerows:多行写入,将一个二位列表中的每一个一维列表分别写入其对应的一行,一维列表中的每个元素对应这一行的单元格
columns = ['姓名', '性别', '年龄', '成绩']
students = [
['张三', '未知', 100, 50],
['李四', '男', 40, 100],
['王五', '男', 40, 100]
]
file_write.writerow(columns)
file_write.writerows(students)
f.close()
使用wps或者excel打开csv表格文件:
1.直接使用wps打开即可
2.使用excel的导入功能打开
09-csv文件的读操作
import csv
f = open('学生成绩.csv', 'r', encoding='utf-8')
# 使用csv模块的reader类对文件进行读操作,返回包含有数据的一个可迭代对象
# 可迭代对象:能够遍历的数据对象
file_read = csv.reader(f)
for row in file_read:
print(row)
f.close()