PYTHON爬虫大作业:豆瓣读书“小说”标签下1000本书籍的爬取与分析 |
您所在的位置:网站首页 › 网络小说结构分析报告 › PYTHON爬虫大作业:豆瓣读书“小说”标签下1000本书籍的爬取与分析 |
PYTHON爬虫大作业:豆瓣读书“小说”标签下1000本书籍的爬取与分析
项目概述
数据爬取数据分析与可视化·书籍标签词云·箱线图与直方图·关联分析
项目报告摘要一、数据爬取二、数据预处理三、数据存储四、数据分析五、结果与可视化六、结论
本文记录笔者大二下学期选修课数据科学导论的期末大作业,新手小白,才疏学浅,欢迎批评指正。
项目概述
本项目框架如下: 数据爬取数据分析与可视化项目报告 数据爬取 import requests import re from bs4 import BeautifulSoup import pymysql.cursors #给出url,爬取页面信息 def getHTMLText(url, kv): try: r = requests.get(url, timeout = 30, headers = kv) r.raise_for_status() #r.encoding = r.apparent_encoding #该语句导致标签显示为乱码 r.encoding = 'utf-8' return r.text except: print('爬取失败') #建立表格 def buildTable(): conn = pymysql.connect( host = '127.0.0.1', user = 'root', passwd = 'sime1234', #数据库密码 db = 'douban_novels', charset = 'utf8mb4' ) cursor = conn.cursor() sql_create1 = '''CREATE TABLE NOVELS( NO INT PRIMARY KEY, TITLE VARCHAR(45), AUTHOR VARCHAR(45), RATING DECIMAL(2,1), PUBLISHER VARCHAR(45)) ''' cursor.execute(sql_create1) print('BOOKS CREATED') sql_create2 = '''CREATE TABLE NOVEL_TAGS( BOOKNO INT, TAG VARCHAR(45)) ''' cursor.execute(sql_create2) print('TAGS CREATED') cursor.close() conn.close() #给出书籍编号、链接与标题,爬取书籍详情信息,形成字典并返回 def getBookInfo(no, href, title): kv = { #略。提示:将头文件的头部信息复制过来,加上引号和逗号形成字典,注意要删掉Accept-Encoding一行。 } html = getHTMLText(href, kv) book = BeautifulSoup(html, 'html.parser') bookInfo = {'author' : '未知', 'rating' : 0.0, 'publisher' : '未知'} bookInfo['no'] = no bookInfo['title'] = title rating = book.find('strong') if rating.string: try: bookInfo['rating'] = float(rating.text) except: pass for keyTag in book.find_all(name = 'span', attrs = {'class' : 'pl'}): if re.search(r'作者', str(keyTag.string)): author = keyTag#.parent for i in range(4): author = author.next_element author = author.replace('\n', '') author = author.replace(' ', '') bookInfo['author'] = author for keyTag in book.find_all(string = '出版社:'): publisher = keyTag.parent for i in range(2): publisher = publisher.next_element publisher = publisher.replace('\n', '') publisher = publisher.replace(' ', '') bookInfo['publisher'] = publisher tags = [] for tag in book.find_all(attrs = {'class' : 'tag'}): tags.append(tag.text) print(tags) bookInfo['tags'] = tags print(bookInfo) return bookInfo #爬取豆瓣读书小说标签下综合排序前1000本小说的信息 def getBooks(): conn = pymysql.connect( host = '127.0.0.1', user = 'root', passwd = 'sime1234', #数据库密码 db = 'douban_novels', charset = 'utf8mb4' ) cursor = conn.cursor() no = 0 start_url = "https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=" kv = { #略。提示:将头文件的头部信息复制过来,加上引号和逗号形成字典,注意要删掉Accept-Encoding一行。 } for i in range(50): print('第{0}页'.format(i + 1)) end_url = str(20 * i) html = getHTMLText(start_url + end_url, kv) topBooks = BeautifulSoup(html, 'html.parser') for book in topBooks.find_all('a'): href = str(book['href']) if re.match(r'https://book.douban.com/subject/', href): title = book.get('title') if title: no += 1 info = getBookInfo(no, href, title) sql_insert1 = "INSERT INTO NOVELS(NO, TITLE, AUTHOR, RATING, PUBLISHER)\ VALUES({0}, '{1}', '{2}', {3}, '{4}')".format(info['no'], \ info['title'], info['author'], str(info['rating']), info['publisher']) cursor.execute(sql_insert1) print(('book{0} stored').format(info['no'])) tags = info['tags'] for i in range(len(tags)): sql_insert2 = "INSERT INTO NOVEL_TAGS(BOOKNO, TAG) VALUES({0}, '{1}')".format(info['no'], tags[i]) cursor.execute(sql_insert2) print(('book{0} tags stored').format(info['no'])) conn.commit() cursor.close() conn.close() if __name__ == '__main__': buildTable() getBooks() 数据分析与可视化 ·书籍标签词云 import pymysql.cursors import wordcloud from scipy.misc import imread #以空格为间隔,将标签连接成一个string def get_tags_str(): conn = pymysql.connect( host = '127.0.0.1', user = 'root', passwd = 'sime1234', #数据库密码 db = 'douban_novels', charset = 'utf8mb4' ) cursor = conn.cursor() sql_select = 'select tag from douban_novels.novel_tags' cursor.execute(sql_select) tags = cursor.fetchall() tags_str = '' for tag in tags: tags_str += tag[0] tags_str += ' ' cursor.close() conn.close() return tags_str #以空格为间隔,将出版社连接成一个string def get_publishers_str(): conn = pymysql.connect( host = '127.0.0.1', user = 'root', passwd = 'sime1234', #数据库密码 db = 'douban_novels', charset = 'utf8mb4' ) cursor = conn.cursor() sql_select = 'select publisher from douban_novels.novels' cursor.execute(sql_select) publishers = cursor.fetchall() publishers_str = '' for publisher in publishers: publishers_str += publisher[0] publishers_str += ' ' cursor.close() conn.close() return publishers_str #生成词云 if __name__ == '__main__': #读取卡通书本图片 mask = imread('book.png') #生成并配置wordcloud对象 w = wordcloud.WordCloud(font_path = 'msyh.ttc', mask = mask,\ #width = 2000, height = 1000, \ background_color = 'white', max_words = 200) #生成标签词云 tags_str = get_tags_str() w.generate(tags_str) w.to_file('tags_wordcloud.png') print('tags_wordcloud.png generated') #生成出版社词云 publishers_str = get_publishers_str() w.generate(publishers_str) w.to_file('publishers_wordcloud.png') print('publishers_wordcloud.png generated') ·箱线图与直方图 import pymysql.cursors import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams['font.family'] = 'SimHei' plt.figure(dpi = 600) #连接数据库 conn = pymysql.connect( host = '127.0.0.1', user = 'root', passwd = 'sime1234', #数据库密码 db = 'douban_novels', charset = 'utf8mb4' ) cursor = conn.cursor() #生成dataframe:图书信息与高分图书信息 sql_select = 'select * from douban_novels.novels' cursor.execute(sql_select) title = [] author = [] rating = [] publisher = [] for book in cursor.fetchall(): title.append(book[1]) author.append(book[2]) if book[3] == 0: rating.append(None) else: rating.append(float(book[3])) if book[4] == '未知': publisher.append(None) else: publisher.append(book[4]) dic = {'TITLE' : title, 'AUTHOR' : author,\ 'RATING' : rating, 'PUBLISHER' : publisher} d = pd.DataFrame(dic) #生成dataframe:图书信息 d_high_rating = d[d['RATING'] >= 8.5] #生成dataframe:高分图书信息 #得到图书各类信息的描绘信息 print('\n' + '1000本小说评分统计信息', end = '\n') d_des = d.describe() d_des.to_csv('1000本小说评分统计信息.csv') print(d_des) print('\n' + '1000本小说作者统计信息', end = '\n') d_aut_des = d['AUTHOR'].describe() d_aut_des.to_csv('1000本小说作者统计信息.csv') print(d_aut_des) print('\n' + '1000本小说出版社统计信息', end = '\n') d_pls_des = d['PUBLISHER'].describe() d_pls_des.to_csv('1000本小说出版社统计信息.csv') print(d_pls_des) #图书评分箱线图 rating_box = d.plot.box(title="1000本小说评分箱线图") plt.grid(linestyle="--", alpha=0.3) plt.savefig('1000本小说评分箱线图.png') plt.show() #将图书信息进行分类统计,统计1000本小说中出现最多的10个出版社的出现次数 pls_group = d_high_rating.groupby('PUBLISHER') pls_group = pls_group.size().reset_index(name='counts') pls_group = pls_group.set_index('PUBLISHER') pls_group = pls_group.sort_values('counts', ascending = False) pls_group = pls_group[0 : 10] pls_bar = pls_group.plot.bar() plt.title('1000本小说中出现最多的10个出版社的出现次数') plt.xlabel('出现次数') plt.ylabel('出版社') pls_bar.legend_.remove() plt.savefig('1000本小说中出现最多的10个出版社的出现次数.png', bbox_inches = 'tight') plt.show() #将高分图书信息进行分类统计,统计1000本小说中,8.5分以上的小说出现最多的10个出版社的出现次数 pls_group = d.groupby('PUBLISHER') pls_group = pls_group.size().reset_index(name='counts') pls_group = pls_group.set_index('PUBLISHER') pls_group = pls_group.sort_values('counts', ascending = False) pls_group = pls_group[0 : 10] pls_bar = pls_group.plot.bar() plt.title('1000本小说中,8.5分以上的小说出现最多的10个出版社的出现次数') plt.xlabel('出现次数') plt.ylabel('出版社') pls_bar.legend_.remove() plt.savefig('1000本小说中,8.5分以上的小说出现最多的10个出版社的出现次数.png', bbox_inches = 'tight') plt.show() #生成datframe:图书标签与高分图书标签 sql_select = '''select * from douban_novels.novels, douban_novels.novel_tags where douban_novels.novels.NO = douban_novels.novel_tags.BOOKNO;''' cursor.execute(sql_select) title = [] author = [] rating = [] publisher = [] tag = [] for book in cursor.fetchall(): title.append(book[1]) author.append(book[2]) if book[3] == 0: rating.append(None) else: rating.append(float(book[3])) if book[4] == '未知': publisher.append(None) else: publisher.append(book[4]) tag.append(book[6]) dic = {'TITLE' : title, 'AUTHOR' : author,\ 'RATING' : rating, 'PUBLISHER' : publisher, 'TAG' : tag} d = pd.DataFrame(dic) #生成datframe:图书标签 d_high_rating = d[d['RATING'] >= 8.5] #生成datframe:高分图书标签 #得到图书标签的描绘信息 print('\n' + '1000本小说标签统计信息', end = '\n') d_tags_des = d['TAG'].describe() d_tags_des.to_csv('1000本小说标签统计信息.csv') print(d_tags_des) #将图书标签进行分类统计,统计1000本小说中出现最多的10个标签的出现次数 tags_group = d.groupby('TAG') tags_group = tags_group.size().reset_index(name='counts') tags_group = tags_group.sort_values('counts', ascending = False) tags_group = tags_group.set_index('TAG') tags_top10 = tags_group[0 : 10] tags_top10_bar = tags_top10.plot.bar() plt.title('1000本小说中出现最多的10个标签的出现次数') plt.xlabel('出现次数') plt.ylabel('标签') tags_top10_bar.legend_.remove() plt.savefig('1000本小说中出现最多的10个标签的出现次数.png', bbox_inches = 'tight') plt.show() #将高分图书标签进行分类统计,统计1000本小说中,8.5分以上的小说出现最多的10个标签的出现次数 tags_group = d_high_rating.groupby('TAG') tags_group = tags_group.size().reset_index(name='counts') tags_group = tags_group.sort_values('counts', ascending = False) tags_group = tags_group.set_index('TAG') tags_top10 = tags_group[0 : 10] tags_top10_bar = tags_top10.plot.bar() plt.title('1000本小说中,8.5分以上的小说出现最多的10个标签的出现次数') plt.xlabel('出现次数') plt.ylabel('标签') tags_top10_bar.legend_.remove() plt.savefig('1000本小说中,8.5分以上的小说出现最多的10个标签的出现次数.png', bbox_inches = 'tight') plt.show() cursor.close() conn.close() ·关联分析 import pymysql.cursors from efficient_apriori import apriori if __name__ == '__main__': conn = pymysql.connect( host = '127.0.0.1', user = 'root', passwd = 'sime1234', #数据库密码 db = 'douban_novels', charset = 'utf8mb4' ) cursor = conn.cursor() sql_select = '''select douban_novels.novels.publisher, douban_novels.novel_tags.tag from douban_novels.novels, douban_novels.novel_tags where douban_novels.novels.NO = douban_novels.novel_tags.BOOKNO;''' cursor.execute(sql_select) transactions = list(cursor.fetchall()) itemsets, rules = apriori(transactions, min_support = 0.003, min_confidence = 0.1) print(rules) with open('出版社与标签的关联.txt', 'w') as f: for rule in rules: f.write(str(rule) + '\n') cursor.close() conn.close() 项目报告 摘要随着数码产品的流行,人们能获得的娱乐形式越来越多样化,影视、音乐、社交媒体等等精彩刺激的娱乐形式,无疑对人们的阅读习 惯造成了极大的冲击。此外,电子书成为了很多人阅读的首选资源,快节奏的生活也使人们的阅读偏好更加偏向于碎片化的阅读。在这个时候,国人的阅读口味究竟呈现出怎样的状态?现在在国内流行的都是什么样的书籍?书籍是我们的精神食粮,通过国人的读偏好,我们得以窥见当代人的精神世界一角,并能从中得到启示与 反思。在本项目中,笔者爬取了豆瓣读书中“小说”标签下,按照综合 排序的前 1000 本小说的信息,并对数据进行分析与可视化,对国人小说阅读偏好做初步的分析。 关键词:爬虫 阅读偏好 数据分析 数据可视化 一、数据爬取本文选择爬取的网站为豆瓣读书,具体爬取对象为:豆瓣读书的小说标签下, 按综合排序的前 1000 本小说。 具体爬取过程如下: 爬取豆瓣读书的小说标签下前 50 页的内容;从爬取的内容中: (1) 遍历名称为’a’的标签,找出链接前缀为’https://book.douban.com/subject/’ 的标签; (2) 标签的’title’属性作为书籍的标题; (3) 对书籍详情链接进行进一步爬取;爬取书籍详情页面: (1) 将上一步中得到的’title’属性作为书籍标题存入字典; (2) 查找名称为’strong’的标签,将标签的 text 属性转化为 float 类型,作为书籍评分存入字典; (3) 查找名称为’span’,’class’属性为’pl’的标签,在查找结果中查找标签的 string 属性为’作者:’的标签,选取标签后的第 4 个元素作为作者存入字 典;查找标签的 string 属性’出版社’的标签,选取标签后的第 2 个元素作 为出版社存入字典; (4) 在爬取过程中,发现部分作者标签的 string 类型为“作者”,缺失了冒号,于是将查找条件修改为:匹配 string 属性含有’作者’字符串的标签; (5) 查找’class’属性为’tag’的标签,将这些标签的’text’属性存储在一个列表 中,然后将列表存入字典; (6) 将字典存入数据库 二、数据预处理在爬取过程中,发现部分书籍的评分或者出版社有缺失的情况,于是: 1.将评分缺失的书籍评分记为 0.0 分; 2.将出版社缺失的书籍记为’未知’; 3.在读取数据库数据并生成 data frame 时,将评分为 0.0,以及出版社为’未知’ 的项读取为 None 三、数据存储本项目选取的存储方式为存入 mysql 数据库。 以下为数据集介绍: 数据库 数据库名称douban_novels表格 1novels表格 2novel_tags书籍信息数据集(不含标签) 表格名称:novels 共包含 1000 条数据 字段名说明NO书籍编号,按照网页上书籍排列顺序编号,从 1 到 1000TITLE书籍标题AUTHOR书籍作者RATING书籍评分PUBLISHER书籍出版社书籍标签数据集 表格名称:novel_tags 共包含 8000 条数据 字段名说明BOOKNO书籍编号(与 novels 表格对应)TAG书籍标签 四、数据分析本项目的数据分析内容包括: 1.小说统计信息 (1)评分统计信息(生成 csv 文件) (2)作者统计信息(生成 csv 文件) (3)出版社统计信息(生成 csv 文件) (4)标签统计信息(生成 csv 文件) 2.小说评分分布(生成箱线图) 3.最受欢迎的小说出版社与标签(生成词云) 4.最受欢迎的小说出版社与标签(生成直方图) 5.高分小说中最受欢迎的出版社与标签(生成直方图) 6.出版社与标签关联分析(生成 txt 文件) 以上各项数据分析使用的分析方法: 1、2、4、5: 主要工具:pandas 库、matplotlib 库 过程: 分别生成 4 个 dataframe,分别为图书信息(不含标签)、高分图书信息 (不含标签)、图书标签、高分图书标签;对图书信息(不含标签)与图书标签两个 dataframe 使用 describe()函数 得到统计信息并存为 csv 文件通过 groupby 函数,得到各个 dataframe 中各出版社、标签出现次数,生 成直方图并保存3(生成词云): 主要工具:wordcloud 库 过程: 分别将出版社和标签,以空格为分隔,形成字符串通过 wordcloud 库的 WordCloud 对象分别生成两个词云并保存6(出版社与标签关联分析): 主要工具:efficient_apriori 库 过程: 将每本小说的出版社与各个标签分别形成的元组存为列表通过 efficient_apriori 库的 apriori 类进行分析,得到关联规则,输出并存 为 txt 文件 五、结果与可视化1.小说统计信息 (1)评分统计信息(生成 csv 文件) (2)作者统计信息(生成 csv 文件) (3)出版社统计信息(生成 csv 文件) (4)标签统计信息(生成 csv 文件) 2.小说评分分布(生成箱线图) 3.最受欢迎的小说出版社与标签(生成词云) 4.最受欢迎的小说出版社与标签(生成直方图) 5.高分小说中最受欢迎的出版社与标签(生成直方图) 6.出版社与标签关联分析(生成 txt 文件) {东野圭吾} -> {南海出版公司} (conf: 0.718, supp: 0.004, lift: 9.447, conv: 3.276) {推理} -> {南海出版公司} (conf: 0.240, supp: 0.004, lift: 3.162, conv: 1.216) {日本文学} -> {南海出版公司} (conf: 0.323, supp: 0.005, lift: 4.251, conv: 1.365) {日本} -> {南海出版公司} (conf: 0.311, supp: 0.006, lift: 4.090, conv: 1.341) {南海出版公司} -> {小说} (conf: 0.113, supp: 0.009, lift: 0.968, conv: 0.996) {北京联合出版公司} -> {小说} (conf: 0.117, supp: 0.004, lift: 0.995, conv: 0.999) {经典} -> {人民文学出版社} (conf: 0.233, supp: 0.005, lift: 2.454, conv: 1.180) {人民文学出版社} -> {小说} (conf: 0.111, supp: 0.011, lift: 0.943, conv: 0.992) {中国} -> {人民文学出版社} (conf: 0.170, supp: 0.003, lift: 1.787, conv: 1.090) {外国文学} -> {人民文学出版社} (conf: 0.121, supp: 0.006, lift: 1.278, conv: 1.030) {中国文学} -> {人民文学出版社} (conf: 0.195, supp: 0.004, lift: 2.057, conv: 1.125) {文学} -> {人民文学出版社} (conf: 0.103, supp: 0.004, lift: 1.088, conv: 1.009) {北京十月文艺出版社} -> {小说} (conf: 0.125, supp: 0.004, lift: 1.066, conv: 1.009) {译林出版社} -> {外国文学} (conf: 0.114, supp: 0.006, lift: 2.349, conv: 1.074) {外国文学} -> {译林出版社} (conf: 0.129, supp: 0.006, lift: 2.349, conv: 1.085) {译林出版社} -> {小说} (conf: 0.123, supp: 0.007, lift: 1.047, conv: 1.006) {小说} -> {上海译文出版社} (conf: 0.102, supp: 0.012, lift: 1.055, conv: 1.006) {上海译文出版社} -> {小说} (conf: 0.124, supp: 0.012, lift: 1.055, conv: 1.007) {外国文学} -> {上海译文出版社} (conf: 0.209, supp: 0.010, lift: 2.158, conv: 1.142) {上海译文出版社} -> {外国文学} (conf: 0.104, supp: 0.010, lift: 2.158, conv: 1.063) {文学} -> {上海译文出版社} (conf: 0.143, supp: 0.006, lift: 1.473, conv: 1.053) {湖南文艺出版社} -> {小说} (conf: 0.121, supp: 0.004, lift: 1.034, conv: 1.005) {江苏凤凰文艺出版社} -> {小说} (conf: 0.117, supp: 0.004, lift: 1.001, conv: 1.000) {上海文艺出版社} -> {小说} (conf: 0.116, supp: 0.003, lift: 0.990, conv: 0.999) {新星出版社} -> {小说} (conf: 0.121, supp: 0.003, lift: 1.028, conv: 1.004) 六、结论从数据分析与可视化的结果中,我们得出如下结论: 豆瓣读书“小说”标签下,按照综合排序前 1000 本小说具有这样的特征: 整体评分较高,平均评分为 8.37,但也有少数评分较低的小说,说明受欢迎的的小说大多为高分优质小说,但也有少量低分作品受到欢迎;最受欢迎的作者、出版社、标签分别为东野圭吾、上海译文出版社以及“小说”;比较最受欢迎的小说出版社与高分小说中最受欢迎的小说出版社,榜首几家出版社变化不大(上海译文出版社、人民文学出版社等出版社都是 名声大、作品质量高的出版社),说明这几个高质量的出版社受到欢迎;其余的出版社在两图中有相对明显差异,高分图书中文艺类出版社更常见,说明这几个文艺类出版社出版小说质量更佳却没有那么受欢迎;比较最受欢迎的小说标签与高分小说中最受欢迎的小说标签,总体差异不大,大多为各国文学的标签。值得注意的是推理小说在最受欢迎的10个小说标签中出现,却没有在高分小说中最受欢迎的 10 个小说标签中出现,说明推理类小说虽受欢迎,总体质量相对其它文学类书籍较低;从关联分析可知,最热门的几个出版社的最受欢迎的小说里,上海译文出版社与译林出版社出版作品多为外国文学,人民文学出版社出版作品则包括了各国作品,南海出版集团出版了较多的日本推理小说(尤其是东野圭吾的小说)并受到欢迎。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |