一、存储数据的方式
同样是存储数据的文件,“csv”格式文件和Excel文件有什么区别呢?
1. CSV文件
- 我们知道json是特殊的字符串。其实,csv也是一种字符串文件的格式,它组织数据的语法就是在字符串之间加分隔符——行与行之间是加换行符,同列之间是加逗号分隔。
- csv格式文件可以用任意的文本编辑器打开(如记事本),也可以用Excel打开,还可以通过Excel把文件另存为csv格式(因为Excel支持csv格式文件)。
- csv文件里的逗号充当分隔同列字符串的作用。分隔符使得数据的组织方式更有规律,这让更容易让我们提取和查找。
2. EXCEL文件
- 它有专门的文件格式,即xls和xlsx(Excel2003版本的文件格式是xls,Excel2007及之后的版本的文件格式就是xlsx)。
3. CSV文件与EXCEL文件的比较
- 用csv格式存储数据,读写比较方便,易于实现,文件也会比Excel文件小。
- Excel文件本身的功能更为强大,比如能嵌入图像和图表,生成公式等。如何选择就看具体的使用场景了。
二、存储数据的基础知识
存储成csv格式文件和存储成Excel文件,这两种不同的存储方式需要引用的模块也是不同的。操作csv文件我们需要借助csv模块;操作Excel文件则需要借助openpyxl模块。
1. CSV文件的读写
import csv
# 需要写入的数据
score1 = ['math', 95]
score2 = ['english', 90]
# 打开文件,追加a, newline="",可以删掉行与行之间的空格
file= open("score.csv", "a", newline="")
# 设定写入模式
csv_write = csv.writer(file)
# 写入具体内容
csv_write.writerow(score1)
csv_write.writerow(score2)
file.close()
- 代码file= open(“score.csv”, “a”, newline="")事实上就是创建了一个csv文件并打开它,等待写入文件。
- 代码csv_write = csv.writer(file),创建了一个csvwrite对象。
- 下面两行代码就用该对象的writerow方法写入列表数据。
import csv
# 打开csv文件
file = open("score.csv")
# 读取文件内容,构造csv.reader对象
reader = csv.reader(file)
# 打印reader中的内容
for item in reader:
print(item)
第二行的代码就是打开我们已有的csv文件,然后构造一个csv.reader对象,最后把reader中的内容输出,读取csv的工作也就完成了。
2. EXCEL文件的读写
安装openpyxl库
- Windows系统:pip install openpyxl
Macx系统:pip3 install openpyxl
EXCEL文件的写入
import openpyxl
# 引用openpyxl
wb = openpyxl.Workbook()
# 利用openpyxl.Workbook()函数创建新的workbook(工作薄)对象,就是创建新的空的Excel文件。
sheet = wb.active
# wb.active就是获取这个工作薄的活动表,通常就是第一个工作簿,也就是我们在上面的图片中看到的sheet1。
sheet.title = 'test'
# 可以用.title给工作表重命名。现在第一个工作表的名称就会由原来默认的“sheet1”改为"kaikeba"。
sheet['A1'] = '天下第一'
# 向单个单元格写入数据
score1 = ['math', 95]
sheet.append(score1)
# 写入整行的数据,变量类型是一个列表
wb.save('score.xlsx')
# 保存修改的Excel
wb.close()
# 关闭Excel
示例代码中我们是用到append方法向Excel写入一行内容,要写入多个内容只需添加一个循环即可。
EXCEL文件的读取
import openpyxl
wb = openpyxl.load_workbook('score.xlsx')
# 打开的指定的工作簿
sheet = wb['天下第一']
# 指定读取的工作表的名称
A1_value = sheet['A1'].value
print(A1_value)
# 获取A1的值
三、爬取并存储周杰伦的歌曲信息
import requests
import openpyxl
# 创建workbook对象,建立工作簿
workbook = openpyxl.Workbook()
# 创建工作表
sheet = workbook.active
# 重命名工作表
sheet.title = 'Jac_chou_songs'
# 插入表头
sheet.append(['页码','歌名','歌曲ID','专辑名称','播放时长','播放链接','歌词'])
# 伪装歌曲请求头
headers = {'orgin': 'https://y.qq.com',
'referer': 'https://y.qq.com/portal/search.htm',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
}
# 歌曲请求的网址
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
# 循环更新页码
for i in range(1,4):
# 歌曲请求参数
param_song = {'ct': '24',
'qqmusic_ver': '1298',
'new_json': '1',
'remoteplace': 'txt.yqq.song',
'searchid': '67279455817994118',
't': '0',
'aggr': '1',
'cr': '1',
'catZhida': '1',
'lossless': '0',
'flag_qc': '0',
'p': i,
'n': '10',
'w': '周杰伦',
'g_tk': '1987388883',
'loginUin': '1285575771',
'hostUin': '0',
'format': 'json',
'inCharset': 'utf8',
'outCharset': 'utf-8',
'notice': '0',
'platform': 'yqq.json',
'needNewCode': '0'}
# 使用requests.get(),获取返回的数据
response = requests.get(url,params=param_song,headers=headers)
# 使用json(),将字符串转为列表/字典
js_music = response.json()
# 层层展开字典,获取歌曲列表
list_musci = js_music['data']['song']['list']
# 遍历歌曲列表,获取每首歌曲的信息
for music in list_musci:
# 歌名
title = music['name']
# 歌曲ID
id = music['id']
# 歌曲所属专辑
album = music['album']['name']
# 歌曲播放时长
time = music['interval']
# 歌曲链接
link = 'https://y.qq.com/n/yqq/song/'+music['mid']+'.html'
# 伪装歌词请求头
headers_lyric = {'origin': 'https://y.qq.com',
'referer': 'https://y.qq.com/n/yqq/song/{}.html'.format(music['mid']),
'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
}
# 歌词url
url_lyric = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg'
# 歌词请求参数
param_lyric = {'nobase64': '1',
'musicid': id,
'-': 'jsonp1',
'g_tk': '1847098181',
'loginUin': '1285575771',
'hostUin': '0',
'format': 'json',
'inCharset': 'utf8',
'outCharset': 'utf-8',
'notice': '0',
'platform': 'yqq.json',
'needNewCode': '0'
}
# 请求返回歌词的数据
response_lyric = requests.get(url_lyric,params=param_lyric,headers=headers)
# 使用json()方法,转换为字典/列表
js_lyric = response_lyric.json()
# 展开字典,获取歌词
lyric = js_lyric['lyric']
# 将歌曲信息写入excel文件中
sheet.append([i,title,id,album,time,link,lyric])
# 打印,以便发现问题
print('页码:'+str(i))
print('歌名:'+title)
print('歌曲ID:'+str(id))
print('专辑名:'+album)
print('播放时长:'+str(time)+'秒')
print('播放链接:'+link)
print('歌词:'+lyric)
# 保存excel文件,并命名为Jay_chou_songs.xlsx
workbook.save('Jay_chou_songs.xlsx')
# 关闭文件
workbook.close()
四、总结
五、练习
- 爬取豆瓣TOP250的电影信息,并存入EXCEL文件中。
import requests
from bs4 import BeautifulSoup
import openpyxl
# 请求头,避免反爬
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'}
# 使用requests.get()获取response对象,循环更新每页的页码
# 创建xlsx工作簿
wb = openpyxl.Workbook()
# 创建工作表
sheet = wb.active
# 将工作表命名为豆瓣电影250
sheet.title = '豆瓣电影TOP250'
# 添加工作表头
sheet.append(['序号', '电影名称', '网址URL', '导演/演员', '评价信息', '影片简介'])
# 观察豆瓣TOP250的影片的URL,规律为每页间隔25.
for i in range(10):
reponse = requests.get(f'https://movie.douban.com/top250?start={i * 25}&filter=', headers=headers)
# 将返回的字符串转换为bs对象
bs_movie = BeautifulSoup(reponse.text, 'html.parser')
# 通过find_all找到包含电影信息的列表
list_movie = bs_movie.find_all('div', class_='item')
# 循环遍历列表,返回每个电影的信息
for movie in list_movie:
# 电影序号
num = movie.find('em').text
# 电影标题
title = movie.find('div', class_='hd').find('a').text.replace(' ', '').replace('\n', '')
# 电影网址URL
url = movie.find('a')['href']
# 电影导演与演员
director = movie.find('p').text.replace(' ', '').replace('\n', '')
# 电影评价信息
rating = movie.find('div', class_='star').text.replace(' ', '').replace('\n', '/')
# 电影简介,因第248条没有简介信息返回,所以使用异常捕捉报错
try:
info = movie.find('p', class_='quote').text.replace('\n', '')
except:
info = None
# 将电影信息逐行写入xlsx文件中
sheet.append([num, title, url, director, rating, info])
# 打印,以便发现问题
print(num)
print(title)
print(director)
print(rating)
print(info)
# 保存文件为"豆瓣点评TOP250.xlsx"
wb.save('豆瓣电影TOP250.xlsx')
# 关闭文件
wb.close()
- 爬取知乎张佳伟的前三页文章,并存入CSV文件中。
import requests
import csv
# 创建csv文件,并命名为"张佳伟.csv",以追加模式写入
file = open('zhangjiawei.csv','a+',newline='')
file_writer = csv.writer(file)
# 写入表头
file_writer.writerow(['序号','文章标题','文章ID','点赞数','评论数','文章简介','文章链接'])
# 伪装请求头
headers = {'referer': 'https://www.zhihu.com/people/zhang-jia-wei/posts',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
}
# 请求的url
url = 'https://www.zhihu.com/api/v4/members/zhang-jia-wei/articles'
x = 1
# 循环更改页码参数
for i in range(4):
# 请求参数
param = {
'include': 'data[*].comment_count,suggest_edit,is_normal,thumbnail_extra_info,thumbnail,can_comment,comment_permission,admin_closed_comment,content,voteup_count,created,updated,upvoted_followees,voting,review_info,is_labeled,label_info;data[*].author.badge[?(type=best_answerer)].topics',
'offset': str(i*20),
'limit': 20,
'sort_by': 'created'
}
# requests.get()返回数据
response = requests.get(url,params=param,headers=headers)
# 使用json(),将字符串转换为字典/列表
js_response = response.json()
# 展开字典,获取文章列表
list_article = js_response['data']
# 遍历列表,获取文章信息
for article in list_article:
# 文章标题
title = article['title']
# 文章简介
content = article['excerpt']
# 文章ID
id = article['id']
# 文章点赞数
voteup = article['voteup_count']
# 文章评论数
comment = article['comment_count']
# 文章URL
url_article = 'https://zhuanlan.zhihu.com/p/{}.html'.format(id)
# 将文章信息写入csv中
file_writer.writerow([x,title,id,voteup,comment,url_article])
# 打印文章信息,以便发现问题
print(x)
print(title)
print(id)
print(voteup)
print(comment)
print(url_article)
print()
x = x + 1
# 关闭文件
file.close()