经过努力,我们终于拿到了数据了。那么下一步就是要将我们获取到的数据保存起来了,这样才能给后续的操作(在网页上展示、数据分析挖掘可视化等等)提供便利。
一般我们保存数据可以采用多种可选载体,根据成本、数据用途我们分别采用适合自己的载体保存数据。
主要的数据保存方法有
写入到文本:txt,csv,excel...
保存到数据库:本地的sqlite、MySQL、mongodb...
由于保存到数据库的操作需要了解数据库相关知识以及软件支持,所以我们本章采用多种文本方式写入。
先回顾一下上一节的代码:
import requestsfrom bs4 import BeautifulSoup # 从bs4引入BeautifulSoup#请求网页url = "https://movie.douban.com/cinema/later/chengdu/"response = requests.get(url)# 解析网页# 初始化BeautifulSoup方法一:利用网页字符串自带的编码信息解析网页soup = BeautifulSoup(response.content.decode('utf-8'), 'lxml')# 初始化BeautifulSoup方法二:手动指定解析编码解析网页# soup = BeautifulSoup(response.content, 'lxml', from_encoding='utf-8')# print(soup) # 输出BeautifulSoup转换后的内容all_movies = soup.find('div', id="showing-soon") # 先找到最大的div# print(all_movies) # 输出最大的div的内容for each_movie in all_movies.find_all('div', class_="item"): # 从最大的div里面找到影片的div # print(each_movie) # 输出每个影片div的内容 all_a_tag = each_movie.find_all('a') all_li_tag = each_movie.find_all('li') movie_name = all_a_tag[1].text moive_href = all_a_tag[1]['href'] movie_date = all_li_tag[0].text movie_type = all_li_tag[1].text movie_area = all_li_tag[2].text movie_lovers = all_li_tag[3].text print('名字:{},链接:{},日期:{},类型:{},地区:{}, 关注者:{}'.format( movie_name, moive_href, movie_date, movie_type, movie_area, movie_lovers))
Python打开文件操作详解
使用file_obj = open("file_name", 'mode', encoding="encoding")
的方法进行操作。file_name
是你需要读取或者写入的文件路径及文件名(如"../data/ok.txt"
是相对路径打开,如果只写一个"ok.txt"
,那么就会默认保存到当前.py文件或者.ipynb文件的相同文件夹里面)mode
是你指定操作文件的方法,常用的有r
,w
,a
,r+
,rb
,wb
,ab
,rb+
这些方法,r
是读取(read,如果不存在则报错),w
是写入(write,文件不存在则创建,如果文件存在则覆盖),a
是追加写入(文件不存在则创建,文件存在从文件最后开始写入),r+
是读取和写入。后面加了个b
的,是以二进制方式进行上述操作(通常用于对图片、视频等二进制文件进行操作),mode默认是r。encoding
在前面的章节说过了,是我们对文件进行操作所遵循的编码,默认为当前运行环境编码。Windows的默认编码是gbk
,linux系统基本上是utf-8
。不同的文件可以有不同的编码,设置读取的编码错误要么会报错,要么就得不到正确的内容。file_obj
是一个文件对象(Python里面也是万物皆对象,所以不要愁没有对象了),之后我们读取、写入数据都通过这个对象进行操作。Python读取文件方法
file_obj.read()
,一次性读取文件所有的内容作为一个字符串。file_obj.readlines()
,一次性读取文件所有内容,但每一行作为一个字符串并放在一个list(数组)里面。file_obj.readline(limit)
,从上次读取的行数开始,读取limit
行,limit默认为1。该方法通常用在由于文件过大不能一次性读取完毕一个文件的时候)。Python写入文件的方法
file_obj.write(anystr)
,该方法接受一个字符串,并将字符串写入。file_obj.writelines(list_of_str)
,该方法接受一个内部全是字符串的list数组,并将所有字符串一行一个写入(自动添加换行符)。关闭文件
file_obj.close()
关闭文件对象。打开了一个文件之后要记得关闭,否则可能会出现不可控的问题。但是如果用with方法打开了文件,则不需要手动关闭文件,在with语句块运行结束后,会自动关闭文件。
示例
# 需要手动关闭文件file_obj = open("ok.txt", 'r', encoding="utf-8") content = file_obj.read() file_obj.close()# 不需要手动关闭文件with open("ok.txt", 'r', encoding="utf-8") as file_obj: content = file_obj.read()
把数据保存到 html 文件
由于txt文件难度较低且所学内容被本小节囊括了,所以我们直接从保存数据到HTML文件开始。
我们的目标是:
网页示例
网页的代码是这样的(为了简洁美观,所以采用了bootstrap的css文件):
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>豆瓣电影即将上映影片信息</title> <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"></head><body><h2 class="text-center">豆瓣电影即将上映影片信息</h2><table class="table table-striped table-hover mx-auto text-center"> <thead> <tr> <th>影片名</th> <th>上映日期</th> <th>影片类型</th> <th>地区</th> <th>关注者数量</th> </tr> </thead> <tbody> <tr> <td><a href="https://movie.douban.com/subject/30212331/">测试名1</a></td> <td>测试日期1</td> <td>测试类型1</td> <td>测试地区1</td> <td>测试关注者1</td> </tr> <tr> <td><a href="https://movie.douban.com/subject/30212331/">测试名2</a></td> <td>测试日期2</td> <td>测试类型2</td> <td>测试地区2</td> <td>测试关注者2</td> </tr> </tbody></table></body></html>
从这个代码,我们可以知道,只要我们重复生成<tbody>标签里面的<tr>...<tr>
中间的内容,并把我们的数据填进去就好了。<tbody>前后的代码我们就只需要复制过来写入就好了。
所以我们就拿着之前的代码开始操作了:
注:python 里面三个"
围起来的字符会被看做是一整个字符串,避免了换行符的麻烦。.format()
这个方法的用法是把字符串里面的{}
字符,按次序一一替换成 format() 接受的所有参数。
import requestsfrom bs4 import BeautifulSoup # 从bs4引入BeautifulSoup#请求网页url = "https://movie.douban.com/cinema/later/chengdu/"response = requests.get(url) # 初始化BeautifulSoup方法一:利用网页字符串自带的编码信息解析网页soup = BeautifulSoup(response.content.decode('utf-8'), 'lxml') # 初始化BeautifulSoup方法二:手动指定解析编码解析网页# soup = BeautifulSoup(response.content, 'lxml', from_encoding='utf-8') # print(soup) # 输出BeautifulSoup转换后的内容all_movies = soup.find('div', id="showing-soon") # 先找到最大的div# print(all_movies) # 输出最大的div的内容html_file = open('data.html', 'w', encoding="utf-8") html_file.write(""" <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>豆瓣电影即将上映影片信息</title> <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <h2 class="text-center">豆瓣电影即将上映影片信息</h2> <table class="table table-striped table-hover mx-auto text-center"> <thead> <tr> <th>影片名</th> <th>上映日期</th> <th>影片类型</th> <th>地区</th> <th>关注者数量</th> </tr> </thead> <tbody> """)for each_movie in all_movies.find_all('div', class_="item"): # 从最大的div里面找到影片的div # print(each_movie) # 输出每个影片div的内容 all_a_tag = each_movie.find_all('a') all_li_tag = each_movie.find_all('li') movie_name = all_a_tag[1].text moive_href = all_a_tag[1]['href'] movie_date = all_li_tag[0].text movie_type = all_li_tag[1].text movie_area = all_li_tag[2].text # 替换字符串里面的 想看 两个字为空,使得更加美观 movie_lovers = all_li_tag[3].text.replace("想看", '') print('名字:{},链接:{},日期:{},类型:{},地区:{}, 关注者:{}'.format( movie_name, moive_href, movie_date, movie_type, movie_area, movie_lovers)) html_file.write(""" <tr> <td><a href="{}">{}</a></td> <td>{}</td> <td>{}</td> <td>{}</td> <td>{}</td> </tr> """.format(moive_href, movie_name, movie_date, movie_type, movie_area, movie_lovers)) html_file.write(""" </tbody> </table> </body> </html> """) html_file.close() print("write_finished!")
运行一下,成功输出。然后我们回到 jupyter 的首页,找到我们的data.html
,点击文件名打开网页,就可以看到如下的结果了,并且我们点击这些影片的名字,都会自动跳转到影片的详情页。
写入结果展示
数据保存到csv文件
首先介绍一下csv文件,这是个类 txt 的表格文件,读取和写入都相对excel的表格文件更加简单方便,所以在数据领域使用较多。
要使用csv模块,我们首先需要import csv
,然后把一个文件对象作为参数传给csv.writer()
或者csv.reader()
,然后我们就对这个writer/reader进行读写操作了。
写入是调用writer的writerow()
方法。writerow方法接受一个由字符串组成的 list 数组,然后就会把这个list的内容按照规定写入到csv文件。
读取则是对reader进行遍历,每一轮遍历的结果返回一行的数据组成的 list数组。
写入示例:
import csv# Windows默认编码是gbk,如果用utf-8,excel打开可能会乱码# newline='' 是为了让writer自动添加的换行符和文件的不重复,防止出现跳行的情况file_obj = open('csvtest.csv', 'w', encoding="gbk", newline='') writer = csv.writer(file_obj) a_row = ['你好', 'hello', 'thank', 'you'] row_2 = ['how', 'are', 'you', 'indian', 'mifans'] writer.writerow(a_row) writer.writerow(row_2) file_obj.close() print('finished!')
我们在Windows文件管理器打开当前代码文件夹,(如果没有指定jupyter启动路径并且是以win+x键启动的jupyter,那么jupyter的代码和生成的文件默认是在你的 C:/USER(用户)/username
文件夹里面,username是你的电脑的用户名。)
找到这个csvtest.csv文件(默认就是excel或者wps格式)并打开
运行结果用excel打开
其实文件内容很简单:用,
隔开不同的列,一行就是一个新的行:
csv文件内容
读取示例:
import csv# 读取的编码要和写入的保持一致file_obj = open('csvtest.csv', 'r', encoding="gbk") reader = csv.reader(file_obj)for row in reader: print(row) file_obj.close() print('finished!')
运行结果输出:
['你好', 'hello', 'thank', 'you'] ['how', 'are', 'you', 'indian', 'mifans'] finished!
OK,下一步我们就试着把影片信息存到csv文件中
import csvimport requestsfrom bs4 import BeautifulSoup # 从bs4引入BeautifulSoup# 请求网页url = "https://movie.douban.com/cinema/later/chengdu/"response = requests.get(url)# 初始化BeautifulSoup方法一:利用网页字符串自带的编码信息解析网页soup = BeautifulSoup(response.content.decode('utf-8'), 'lxml')# 初始化BeautifulSoup方法二:手动指定解析编码解析网页# soup = BeautifulSoup(response.content, 'lxml', from_encoding='utf-8')# print(soup) # 输出BeautifulSoup转换后的内容all_movies = soup.find('div', id="showing-soon") # 先找到最大的div# print(all_movies) # 输出最大的div的内容csv_file = open('data.csv', 'w', encoding="gbk", newline='') writer = csv.writer(csv_file) writer.writerow(["影片名", "链接", "上映日期", "影片类型", "地区", "关注者"]) # 写入标题for each_movie in all_movies.find_all('div', class_="item"): # 从最大的div里面找到影片的div # print(each_movie) # 输出每个影片div的内容 all_a_tag = each_movie.find_all('a') all_li_tag = each_movie.find_all('li') movie_name = all_a_tag[1].text moive_href = all_a_tag[1]['href'] movie_date = all_li_tag[0].text movie_type = all_li_tag[1].text movie_area = all_li_tag[2].text movie_lovers = all_li_tag[3].text.replace("想看", '') print('名字:{},链接:{},日期:{},类型:{},地区:{}, 关注者:{}'.format( movie_name, moive_href, movie_date, movie_type, movie_area, movie_lovers)) writer.writerow([movie_name, moive_href, movie_date, movie_type, movie_area, movie_lovers]) csv_file.close() print("write_finished!")
用excel打开的结果
以上就是一部分常见的对数据的保存方式了。如果能够对你学习Python与爬虫的过程起到一点微小的作用,那将是我的无比荣幸。感谢观看。
作者:皮卡丘丶
链接:https://www.jianshu.com/p/011abdcee7e4
共同学习,写下你的评论
评论加载中...
作者其他优质文章