• 一位同学的Python大作业【分析当当网书籍价格、出版社、电子书版本占比数据】


    前言

    本次案例实现目标

    • 书籍基本数据
    • 实现可视化图表
    • 书籍评论数据
    • 评论可以实现词云图

    最基本思路流程: <通用>

    一. 数据来源分析
    1. 只有当你知道你想要数据内容, 是来自于哪里的时候, 才能通过代码请求得到数据
    2. 打开 F12 开发者工具进行抓包分析
    3. 通过关键字进行搜索查询 数据包是请求那个url地址
    二. 代码实现步骤过程: 代码实现基本四大步骤
    1. 发送请求, 模拟浏览器对于url地址<刚刚分析得到的url地址>发送请求
    2. 获取数据, 获取服务器返回响应数据 —> 开发者工具里面 response
    3. 解析数据, 提取我们想要的数据内容 —> 书籍基本信息
    4. 保存数据, 把数据内容保存到表格里面

    代码实现

    获取书籍详情信息

    发送请求
    url = f'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent7-0-0-1-1'
    # 代码模拟浏览器发送请求 ---> headers请求头 <可以复制粘贴>
    headers = {
        # User-Agent 用户代理 表示浏览器基本身份标识
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    # 发送请求
    response = requests.get(url=url, headers=headers)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    解析数据
    # 转换数据类型 ---> 可解析对象
    selector = parsel.Selector(response.text)
    # 第一次提取, 获取所有li标签
    lis = selector.css('.bang_list_mode li')  # 返回列表
    # for循环遍历, 把列表里面的元素一个一个提取出来
    for li in lis:
        title = li.css('.name a::attr(title)').get()  # 标题/书名
        recommend = li.css('.tuijian::text').get().replace('推荐', '')  # 推荐
        star = li.css('.star a::text').get().replace('条评论', '')  # 评价
        author = li.css('div:nth-child(5) a:nth-child(1)::attr(title)').get()  # 作者
        date = li.css('div:nth-child(6) span::text').get()  # 出版日期
        press = li.css('div:nth-child(6) a::text').get()  # 出版社
        price_r = li.css('.price .price_r::text').get()  # 原价
        price_n = li.css('.price .price_n::text').get()  # 售价
        price_e = li.css('.price_e span::text').get()  # 电子书价格
        href = li.css('.name a::attr(href)').get()  # 详情页
        dit = {
            '标题': title,
            '推荐': recommend,
            '评价': star,
            '作者': author,
            '出版日期': date,
            '出版社': press,
            '原价': price_r,
            '售价': price_n,
            '电子书价格': price_e,
            '详情页': href,
        }
        csv_writer.writerow(dit)
        print(dit)
    
    • 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
    保存数据
    f = open('书籍.csv', mode='a', encoding='utf-8', newline='')
    csv_writer = csv.DictWriter(f, fieldnames=[
        '标题',
        '推荐',
        '评价',
        '作者',
        '出版日期',
        '出版社',
        '原价',
        '售价',
        '电子书价格',
        '详情页',
    ])
    # 写入表头
    csv_writer.writeheader()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    运行代码得到结果


    可视化图表

    书籍总体价格区间
    pie1 = (
        Pie(init_opts=opts.InitOpts(theme='dark',width='1000px',height='600px'))
        
        .add('', datas_pair_1, radius=['35%', '60%'])
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title="当当网书籍\n\n原价价格区间", 
                pos_left='center', 
                pos_top='center',
                title_textstyle_opts=opts.TextStyleOpts(
                    color='#F0F8FF', 
                    font_size=20, 
                    font_weight='bold'
                ),
            )
        )
        .set_colors(['#EF9050', '#3B7BA9', '#6FB27C', '#FFAF34', '#D8BFD8', '#00BFFF', '#7FFFAA'])
    )
    pie1.render_notebook() 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    pie1 = (
        Pie(init_opts=opts.InitOpts(theme='dark',width='1000px',height='600px'))
        
        .add('', datas_pair_2, radius=['35%', '60%'])
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title="当当网书籍\n\n售价价格区间", 
                pos_left='center', 
                pos_top='center',
                title_textstyle_opts=opts.TextStyleOpts(
                    color='#F0F8FF', 
                    font_size=20, 
                    font_weight='bold'
                ),
            )
        )
        .set_colors(['#EF9050', '#3B7BA9', '#6FB27C', '#FFAF34', '#D8BFD8', '#00BFFF', '#7FFFAA'])
    )
    pie1.render_notebook() 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    各个出版社书籍数量柱状图
    bar=(
        Bar(init_opts=opts.InitOpts(height='500px',width='1000px',theme='dark'))
        .add_xaxis(counts.index.tolist())
        .add_yaxis(
            '出版社书籍数量',
            counts.values.tolist(),
            label_opts=opts.LabelOpts(is_show=True,position='top'),
            itemstyle_opts=opts.ItemStyleOpts(
                color=JsCode("""new echarts.graphic.LinearGradient(
                0, 0, 0, 1,[{offset: 0,color: 'rgb(255,99,71)'}, {offset: 1,color: 'rgb(32,178,170)'}])
                """
                )
            )
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title='各个出版社书籍数量柱状图'),
                xaxis_opts=opts.AxisOpts(name='书籍名称',
                type_='category',                                           
                axislabel_opts=opts.LabelOpts(rotate=90),
            ),
            yaxis_opts=opts.AxisOpts(
                name='数量',
                min_=0,
                max_=29.0,
                splitline_opts=opts.SplitLineOpts(is_show=True,linestyle_opts=opts.LineStyleOpts(type_='dash'))
            ),
            tooltip_opts=opts.TooltipOpts(trigger='axis',axis_pointer_type='cross')
        )
    
        .set_series_opts(
            markline_opts=opts.MarkLineOpts(
                data=[
                    opts.MarkLineItem(type_='average',name='均值'),
                    opts.MarkLineItem(type_='max',name='最大值'),
                    opts.MarkLineItem(type_='min',name='最小值'),
                ]
            )
        )
    )
    bar.render_notebook()
    
    • 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

    电子书版本占比
    c = (
        Liquid()
        .add("lq", [1-per], is_outline_show=False)
        .set_global_opts(title_opts=opts.TitleOpts(title="电子书版本占比"))
    )
    c.render_notebook()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    书籍评论数据

    for page in range(1, 11):
        time.sleep(1)
        # 确定请求url地址
        url = 'http://product.dangdang.com/index.php'
        # 请求参数
        data = {
            'r': 'comment/list',
            'productId': '29129370',
            'categoryPath': '01.43.79.01.00.00',
            'mainProductId': '29129370',
            'mediumId': '0',
            'pageIndex': page,
            'sortType': '1',
            'filterType': '1',
            'isSystem': '1',
            'tagId': '0',
            'tagFilterCount': '0',
            'template': 'publish',
            'long_or_short': 'short',
        }
        # headers 请求头
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
        }
        # 发送请求
        response =  requests.get(url=url, params=data, headers=headers)
        # response.json() 获取响应json字典数据 键值对取值 ---> 根据冒号左边的内容, 提取冒号右边的内容
        html_data = response.json()['data']['list']['html']
        content_list = re.findall("(.*?)", html_data)
        with open('评论.txt', mode='a', encoding='utf-8') as f:
            f.write('\n'.join(content_list))
            f.write('\n')
            print(content_list)
    
    • 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

    词云

    import jieba # 分词模块 pip install jieba
    import wordcloud
    import imageio
    img = imageio.imread('123.png')
    # wordcloud
    # 1. 打开文件 获取弹幕数据
    # mode='r' 一定要写吗  不一定 默认以 r
    # encoding='' 要写吗?  肯定要的
    f = open('评论.txt', mode='r', encoding='utf-8')
    txt = f.read()
    # print(txt)
    # 2. jieba分词 分割词汇
    txt_list = jieba.lcut(txt)
    # print(txt_list)
    # 列表转字符串怎么转
    string = ' '.join(txt_list)
    # print(string)
    # 3. 词云图设置
    wc = wordcloud.WordCloud(
        width=800,  # 宽度
        height=500, # 高度
        background_color='white', # 背景颜色
        mask=img, # 设置图片样式
        font_path='msyh.ttc',
        scale=15,
        stopwords={'了', '的'},
        contour_width=5,
        contour_color='red'
    )
    # 4. 输入文字内容 (字符串的形式)
    wc.generate(string)
    # 5. 输出图片
    wc.to_file('output2.png')
    
    • 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

    👇问题解答 · 源码获取 · 技术交流 · 抱团学习请联系👇
  • 相关阅读:
    30多岁的每一步都很重要
    小公司需要使用微服务架构吗?
    C++继承
    安卓调用手机邮箱应用发送邮件
    后缀自动机(SAM)讲解
    微信小程序组件传值
    4.新建模块和代码生成
    SAP abap json序列化
    餐厅预订APP多少钱一套?餐厅预订APP如何收费?
    Integer类型比较大小【详解】
  • 原文地址:https://blog.csdn.net/m0_48405781/article/details/126874263