BeautifulSoup4、数据持久化

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()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老树盘根_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值