2022年 11月 9日

python课程设计——当当网Python图书数据分析

一、数据获取

本次项目数据来源为爬虫获取,目标为为当当网上关于python的书籍
爬虫主要思路:通过观察当当网,观察结构,选用适合的方法。先进行单页的数据爬取,再进行多页爬取;解析方法为xpath方法,爬取目标为:书名、价格、作业、出版社、出版时间、商品链接、评论数量;最后将爬取的数据保存到csv文件当中。
爬虫代码如下:

import requests
from lxml import etree
import re
import csv
def get_page():
    # 数据的多页爬取,经过观察,所有页面地址中,有一个唯一的参数page_index发生改变
    # 通过对参数page_index的for循环,遍历每一页的页面,实现多页爬取
    for page in range(1, 101):
        url = 'http://search.dangdang.com/?key=python&act=input&page_index=1' + str(
            page + 1) + '#J_tab'
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                          '(KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
        }
        response = requests.get(url=url, headers=headers)
        parse_page(response)
        # 可以在操作页面实时观察爬取的进度
        print('page %s' % page)
def parse_page(response):
    # 通过etree将图书的七项信息封装为一条数据,保存到data列表当中
    tree = etree.HTML(response.text)
    li_list = tree.xpath('//ul[@class="bigimg"]/li')
    for li in li_list:
        data = []
        try:
            # 通过xpath的方法对所需要的信息进行解析
            # 1、获取书的标题,并添加到列表中
            title = li.xpath('./a/@title')[0].strip()
            data.append(title)
            # 2、获取价格,并添加到列表中
            price = li.xpath('./p[@class="price"]/span[1]/text()')[0]
            data.append(price)
            # 3、获取作者,并添加到列表中
            author = ''.join(li.xpath('./p[@class="search_book_author"]/span[1]//text()')).strip()
            data.append(author)
            # 4、获取出版社
            publis = ''.join(li.xpath('./p[@class="search_book_author"]/span[3]//text()')).strip()
            data.append(publis)
            # 5、获取出版时间,并添加到列表中
            time = li.xpath('./p[@class="search_book_author"]/span[2]/text()')[0]
            pub_time = re.sub('/', '', time).strip()
            data.append(pub_time)
            # 6、获取商品链接,并添加到列表中
            commodity_url = li.xpath('./p[@class="name"]/a/@href')[0]
            data.append(commodity_url)
            # 7、获取评论数量,并添加到列表中
            comment = li.xpath('./p[@class="search_star_line"]/a/text()')[0].strip()
            data.append(comment)
        except:
            pass
        save_data(data)

def save_data(data):
    writer.writerow(data)
def main():
    key = 'python书籍222'  # input('Please input key:')
get_page(key)
# 将所有的数据储存到csv文件当中
fp = open('python书籍3.csv', 'w', encoding='utf-8-sig', newline='')
writer = csv.writer(fp)
header = ['书名', '价格', '作者', '出版社', '出版时间', '商品链接', '评论数量']
writer.writerow(header)
main()
fp.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

爬虫部分结果展示:
在这里插入图片描述

二、数据整理分析

本项目对价格、出版社以及评论进行分析

1、价格

(1)数据预处理

通过观察爬取下来的数据发现,部分数据存在空值,影响分析,所以多价格列进行简单的数据预处理操作,将有空值的整条数据删除

利用pandas库中的null函数查询是否有空值,有空值就将其整条数据删除
import pandas as pd
# 读取文件
df = pd.read_csv(r'D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍.csv')
# 对价格列进行操作
index = df['价格'].notnull()
df = df[index]
# 将处理好的文件保存为python书籍2
df.to_csv(r'D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍2.csv')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(2)数据分类操作

然后对价格列进行分类,将其分为三个类别,分别为价格在30元以下的,价格在30元到70元之间的,价格在70元以上的,注意数据的数据的类型是什么,是否需要类型的转换。

import csv
# 打开存放书籍的文档并读取
file = open('D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍2.csv', encoding='utf-8')
fileReader = csv.reader(file)
data = []
# s1、s2、s3分别为30元以下,30到70元,70元以上
s1 = []
s2 = []
s3 = []
filedata = list(fileReader)
for i in filedata:
    # 选中价格的一列
    m = i[1:2]
    data.append(''.join(m))
for m in range(1,6000):
    # 将价格强制转换为float类型
    if float(data[m]) < 30.00:
        # 将价格低于30元的存放到s1
        s1.append(data[m])
    elif float(data[m]) > 70.00:
        # 价格将高于70元的存放到s3
        s3.append(data[m])
    else:
        # 将价格在30到70元的存放到s2
        s2.append(data[m])
# 同时输出s1、s2、s3的长度来代表其数量
print(len(s1))
print(len(s2))
print(len(s3))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

(3)数据的聚类算法

同时对价格进行一个聚类算法的运用,主要作用为练习使用聚类算法

import jieba
import collections
import wordcloud
import matplotlib.pyplot as plt

# 存放去停用词
stopword_list = []
# 存放分词
object_list = []
# 去停用词
for word in open("D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\stopwords.txt", 'rb'):
    stopword_list.append(word.strip())
# 文本分词
fn = open("D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\Comment_Data.txt", "rb").read()
seg_list_exaut = jieba.cut(fn)
for i in seg_list_exaut:
    if i.encode("utf-8") not in stopword_list:
        object_list.append(i)
# 词频统计、排序
word_counts = collections.Counter(object_list)
word_counts_top10 = word_counts.most_common(10)
print(word_counts_top10)
# 词图云展示
wc = wordcloud.WordCloud(
    font_path=r'C:\Windows\Fonts\simhei.ttf',
    background_color="white",
    margin=5, width=1000,
    height=800,
    max_words=1000,
    max_font_size=200)
wc.generate_from_frequencies(word_counts)
wc.to_file('DangDangWang_WordCloud_show.jpg')
plt.imshow(wc)
plt.axis("off")
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

聚类算法的结果
在这里插入图片描述
在这里插入图片描述

2、出版社

对于出版社的分析主要为统计出版社的数量,并对每个出版社出版关于python的书籍的数量进行统计分析,因此需要对数据进行去重处理

(1)数据预处理

数据的去重处理

file = open('D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍.csv', encoding='utf-8')
fileReader = csv.reader(file)
filedata = list(fileReader)
data = []

for i in filedata:
    # 数据表第四列为出版社
    t = i[3:4]
    data.append(''.join(t))

# 去重
punlish_Number = len(set(data))
print('出版社共'+str(punlish_Number)+'个')
punlish_data = list(set(data))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(2)统计

对出版社的种类以及数量进行统计

# 统计出版社
dict = {}
for i in data:
dict[i] = dict.get(i,0)+1
# 输出所有的出版社以及个数
print(dict)
# print(len(dict))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果展示
在这里插入图片描述
由结果可知出版社共有50个,选取前十名的出版社进行保存
在这里插入图片描述

3、评论数量

通过观察处理,发现存在很多数据没有评论,因此需要进行预处理
对没有评论数量的数据进行删除操作

import pandas as pd
# 读取文件
df = pd.read_csv(r'D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍.csv')
# 对价格列进行操作
index = df['评论数量'].notnull()
df = df[index]
df.to_csv(r'D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍3.csv')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果展示
在这里插入图片描述
对评论数量进行排序,选取评论数量前十的书籍进行展示
在这里插入图片描述

三、数据可视化

1、价格

结果展示
在这里插入图片描述
代码

import matplotlib.pyplot as plt
# 设置中文显示
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
labels = '30元以下', '30到70元', '70元以上'
fraces = [125, 3427, 2447]
# 使画出来的图形为标准圆
plt.axes(aspect=1)
# 突出分离出数量最多的第二部分
explode = [0, 0.1, 0]
colors = ['skyblue', 'pink', 'yellow']
plt.pie(x=fraces,
        labels=labels,
        colors=colors,
        # 显示比例
        autopct='%0f%%',
        explode=explode,
        # 显示阴影,使图形更加美观
        shadow=True)
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

2、出版社

结果展示
在这里插入图片描述
代码

import matplotlib.pyplot as plt

# 设置中文显示
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

num_list = [1530, 1390, 1255, 625,194,100,99,95,93,93]
name_list = ['人民邮电出版社','机械工业出版社','电子工业出版社',
             '清华大学出版社','北京大学出版社','中国水利水电出版社','中国铁道出版社',
             '东南大学出版社','华中科技大学出版社','重庆大学出版社']
plt.barh(range(len(num_list)),
        num_list,
        align="center",
        # 设置标签
        tick_label=name_list,)
plt.title('出版社前十柱状图')
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3、评论

本项分析选取评论数量第一的书,将其所有的评论进行了爬取,并制作词云图进行展示
评论爬取代码

file = open('D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\python书籍4.csv', encoding='utf-8')
fileReader = csv.reader(file)
filedata = list(fileReader)
books_number = []
for i in filedata:
    t = (i[5:6])
    books_number.append(''.join(t))
print(books_number)
for j in range(1, 6):
    for i in range(1, 21):
        url = 'http://product.dangdang.com/index.php?r=comment%2Flist&productId=' + books_number[j] + \       '&categoryPath=01.54.06.19.00.00&mainProductId=25580336&mediumId=0&pageIndex=' + str(i) + \             '&sortType=1&filterType=1&isSystem=1&tagId=0&tagFilterCount=0&template=publish'
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/'
                          '87.0.4280.88 Safari/537.36'}
        print(url)
        req = urllib.request.Request(url, headers=headers)
        response = urllib.request.urlopen(req)
        unicodester = json.load(response)
        html = unicodester["data"]["list"]["html"]
        pattern = re.compile('<span><a href.*?>(.*?)<\/a><\/span>', re.S)
        comments = re.findall(pattern, html)
        print("正在爬取第" + str(i) + "页评论")
        with open('Comment_Data.txt', 'a') as txt:
            txt.write(str(comments) + "\n")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

结果展示
在这里插入图片描述
因为我的停用词没有筛选好,导致制作出来的词云图不够规范,大家可以根据自己的需要对停用词进行添加
代码

import jieba
import collections
import wordcloud
import matplotlib.pyplot as plt

# 存放去停用词
stopword_list = []
# 存放分词
object_list = []
# 去停用词
for word in open("D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\stopwords.txt", 'rb'):
    stopword_list.append(word.strip())
# 文本分词
fn = open("D:\pythonApp\pyproject\我的python\网络大数据采集\dangdang\Comment_Data.txt", "rb").read()
seg_list_exaut = jieba.cut(fn)
for i in seg_list_exaut:
    if i.encode("utf-8") not in stopword_list:
        object_list.append(i)
# 词频统计、排序
word_counts = collections.Counter(object_list)
word_counts_top10 = word_counts.most_common(10)
print(word_counts_top10)
# 词图云展示
wc = wordcloud.WordCloud(
    font_path=r'C:\Windows\Fonts\simhei.ttf',
    background_color="white",
    margin=5, width=1000,
    height=800,
    max_words=1000,
    max_font_size=200)
wc.generate_from_frequencies(word_counts)
wc.to_file('DangDangWang_WordCloud_show.jpg')
plt.imshow(wc)
plt.axis("off")
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

四、总结

本次项目做的比较仓租,看上去有些粗糙,有些细节和部分没有完全实现,以后有时间会对本项目进行完善翻新。同时欢迎大家与我进行交流,希望本次项目内容会对大家有所帮助。

参考:https://blog.csdn.net/qq_48967283/article/details/120898557