计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架

[毕业设计]2023-2024年最新最全计算机专业毕设选题推荐汇总

感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人 。

项目说明

1、介绍

这款汽车信息网站是基于多项技术和框架设计的全面的汽车信息展示及查询系统。其中,采用了Python Django框架和Scrapy爬虫技术实现数据的抓取和处理,结合MySQL数据库进行数据存储和管理,利用Vue3、Element-Plus、ECharts以及Pinia等前端技术实现了丰富的数据可视化展示和用户交互功能。

(1)系统介绍页
计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第1张图片

(2)项目首页
计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第2张图片

2、技术说明:

  1. Scrapy 爬虫框架:用于抓取懂车帝和车质网的汽车数据和投诉数据。
  2. MySQL 数据库:存储抓取到的数据。
  3. Django Web 框架:用于构建整个 Web 应用程序,同时使用 Django SimpleUI 作为后台管理系统。
  4. Vue.js 前端框架:用于构建所有的前端视图以及实现单页应用程序。
  5. Element Plus UI 组件库:在 Vue.js 中使用 Element Plus UI 组件库实现各种表单元素、按钮、对话框、消息框、布局等等。
  6. ECharts 图表库:使用 ECharts 可视化组件库实现柱状图、雷达图、关系图、词云、时间轴等数据可视化功能。
  7. Vue Router:用于实现前端路由,支持 URL 路径映射和状态管理等。
  8. Pinia:使用 Pinia 实现 Vuex 类似的状态管理模式,方便组织和管理 Vue.js 应用程序中的复杂状态逻辑。
  9. Python 后端语言:使用 Python 编写后端代码,完成数据处理、Web 接口设计等相关工作。

3、项目截图

(1)数据可视化分析计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第3张图片
(2)销量榜单

计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第4张图片
(3)汽车信息页面

计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第5张图片

(4)差评榜单
计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第6张图片

(5)后台数据管理

计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第7张图片

(6)爬虫数据采集页面

计算机毕业设计:基于python汽车数据采集分析可视化系统+爬虫+django框架_第8张图片

4、系统主要包含模块:

  1. Scrapy爬虫:使用Scrapy框架抓取了“懂车帝”网站的汽车及销量数据,以及“车质网”的汽车投诉数据,并将这些数据存储进MySQL数据库中,为后续的展示和查询提供了数据基础。
  2. 条件选车模块:通过用户输入关键词、选择品牌、价格、燃料类型、座位、车型等条件,实现对车系的筛选,并提供了按总分、价格、舒适性、外观、配置、控制、动力、空间、内饰等维度对筛选结果的排序,并支持自动翻页功能。
  3. 销量榜单模块:根据近一年、近半年以及每个月的车系销量数据进行统计,并展示排名,为用户提供参考。
  4. 差评榜单模块:根据近一年、近半年以及每个月的车系问题投诉数据进行统计,并展示排名,同时可以筛选质量问题、服务问题、其他问题,为用户提供更加精准的信息。
  5. 可视化分析模块:包括车系降价排行榜柱状图可视化(官方价减去经销商价格得到降差价)、汽车品牌数量TOP分布图(分析前30个品牌的车系数量的分布)、价格范围数量分布图(对分布在0-10万 10-15万 15-20万 20-25万 25-30万 30-40万 50万以上价格范围的车系数量进行分析),为用户提供更加直观的数据呈现。
  6. 车系详情页面:介绍了品牌、车系名、经销商报价、厂商报价、近一年销量排名、投诉量排名等基本信息,并展示了评分雷达图分析面板,分析车系的舒适性、外观、配置、控制、动力、空间、内饰六个维度,同时展示汽车数据面板和外观图片,以及该车型的所有投诉问题标签。使用ECharts展示了每个月的质量问题关键词、三种问题的每月投诉量走势图、每月车系销量走势图、每月销量排名走势图。
  7. 后台管理模块:可以对所有数据进行增删改查的管理,方便管理员对数据进行维护和管理。
  8. 用户登陆注册:用户可以通过注册登陆功能,实现个人信息的管理和保存。
    综上所述,该汽车信息网站具有多项功能,不仅提供了全面的汽车信息查询和展示功能,同时也通过数据可视化的方式为用户提供了更加丰富的数据分析和决策支持,是一款集数据处理、UI设计、前端交互、后台管理等于一体的全面性汽车信息系统。

5、各模块功能实现:

  1. scrapy爬虫抓取数据
    (1)懂车帝网站的汽车及销量数据:
  • 创建基于Scrapy框架的新项目;
  • 根据懂车帝网站的目录结构和页面布局编写对应的Spider程序,提取汽车及销量信息;
  • 将提取到的数据保存到MySQL数据库中。
    (2)车质网的汽车投诉数据:
  • 根据车质网的目录结构和页面布局编写对应的Spider程序,提取汽车问题投诉信息;
  • 将提取到的数据保存到MySQL数据库中。
  1. 条件选车模块
    (1)后端实现
  • 根据Vue.js框架开发前端页面,设计筛选条件和排序方式,对筛选条件进行处理后,向Django API发送请求获取车系数据;
  • 设计Django API,根据前端发来的请求参数从MySQL数据库中查询车系数据,并按照排序方式进行排序并返回给前端。
    (2)前端实现
  • 使用Element Plus UI以及ECharts可视化组件库渲染页面上的各种表单元素、按钮和图表;
  • 使用Vue Router进行路由管理,将不同的功能模块划分为不同的页面;
  • 实现分页功能,每次翻页时请求新的数据。
  1. 销量榜单模块
    (1)后端实现
  • 设计Django API,根据时间范围(近一年、近半年、每个月)获取车系销量数据并进行统计;
  • 根据前端发来的请求参数返回相应的车系销量排名。
    (2)前端实现
  • 使用Element Plus UI等组件对页面进行美化和交互设计。
  1. 差评榜单模块
    (1)后端实现
  • 设计Django API,根据时间范围和问题类型对投诉数据进行统计,并返回给前端。
    (2)前端实现
  • 使用Element Plus UI等组件对页面进行美化和交互设计。
  1. 可视化分析模块
    (1)后端实现
  • 设计Django API,统计降价排行榜、汽车品牌数量TOP分布和价格范围数量分布等指标;
  • 调用ECharts库实现可视化展示,使用Vue.js进行页面设计,使用Element Plus UI组件库对页面进行美化。
    (2)前端实现
  • 使用ECharts图表库生成柱状图、词云和时间轴等展示效果;
  • 使用Element Plus UI进行页面美化和交互设计。
  1. 车系详情页面
    (1)后端实现
  • 设计Django API,根据车系ID获取相应的汽车数据并返回给前端。
    (2)前端实现
  • 使用Vue.js框架开发前端页面,调用Django API获取后端数据;
  • 使用Element Plus UI进行页面美化和交互设计;
  • 在雷达图、词云和时间轴等展示中,借助ECharts图表库实现可视化效果。
  1. 可在后台增删改查管理所有数据
    使用Django SimpleUI实现管理后台,并且配置相应的权限控制,管理员可以登录后台,对汽车数据和投诉数据进行增删改查和其他操作。

  2. 用户登陆注册
    (1)后端实现

  • 使用Django框架自带的用户认证系统,实现用户登录和注册功能。
  • 根据前端发来的请求验证用户信息。
    (2)前端实现
  • 借助Element Plus UI实现表单和对话框等交互组件,提高系统的易用性。

6、部分代码

from django.shortcuts import render
from datetime import datetime, timedelta
from .models import *
from django.http.response import JsonResponse
from itertools import groupby
from .models import *
import json
from django.http.response import HttpResponse
from django.shortcuts import render
from django.http import JsonResponse
from pyecharts import options as opts
from pyecharts.charts import Map, Grid, Bar, Line, Pie, WordCloud, Radar, Timeline
from pyecharts.faker import Faker
from pyecharts.commons.utils import JsCode
from pyecharts.options.charts_options import MapItem
from datetime import datetime, time
from django.core.paginator import Paginator
from django.db.models import Q, F
from pyecharts.globals import SymbolType
from django.db.models import Sum, Count, Max, Min, Avg
from collections import Counter
from requests_html import requests
from itertools import chain
from functools import lru_cache


def to_dict(l, exclude=tuple(), single=False):
    # 将数据库模型 变为 字典数据 的工具类函数
    def transform(v):
        if isinstance(v, datetime):
            return v.strftime("%Y-%m-%d %H:%M:%S")
        return v

    def _todict(obj):
        j = {
            k: transform(v)
            for k, v in obj.__dict__.items()
            if not k.startswith("_") and k not in exclude
        }
        return j

    if single:
        return _todict(l)
    return [_todict(i) for i in l]


def all_grouped_brands(request):
    """
    返回按拼音分组的所有品牌的JSON响应。

    Args:
        request (HttpRequest): HTTP请求对象。

    Returns:
        JsonResponse: 按拼音分组的所有品牌的JSON响应。
    """
    # 获取请求数据
    data = request.json

    # 获取所有品牌并转换为字典
    brands = to_dict(Brand.objects.all().order_by("pinyin", "-on_sale_series_count"))

    # 按拼音分组品牌
    result = [(i[0], list(i[1])) for i in groupby(brands, key=lambda x: x["pinyin"])]

    # 返回JSON响应
    return JsonResponse(result, safe=False)


def query_car_series(request):
    """根据请求参数查询车系。

    Args:
        request (HttpRequest): HTTP请求。

    Returns:
        JsonResponse: 包含车系的JSON响应。
    """
    # 获取请求参数
    body = request.json
    pagesize = body.get("pagesize", 10)
    page = body.get("page", 1)
    exclude_fields = ["pagesize", "page", "total", "orderby"]
    orderby = body.get("orderby")

    # 从请求参数构建查询
    query = {k: v for k, v in body.items() if k not in exclude_fields and v}
    q = Q(**query)

    # 获取车系对象并对结果进行分页
    objs = CarSeries.objects.filter(q).order_by(orderby)
    paginator = Paginator(objs, pagesize)

    # 获取指定页面并将结果转换为字典列表
    try:
        pg = paginator.page(page)
        result = list(pg.object_list)
    except Exception as e:
        result = []

    result = to_dict(result)

    # 将结果作为JSON响应返回
    return JsonResponse({"total": paginator.count, "records": result})


def lasted_sales_rank_months(request):
    months = list(
        CarSale.objects.values_list("month", flat=True)
        .order_by("-month")
        .distinct()[:24]
    )
    return JsonResponse(months, safe=False)


def lasted_sales_issue_months(request):
    months = list(
        CarIssue.objects.values_list("stime", flat=True)
        .order_by("-stime")
        .distinct()[:24]
    )
    return JsonResponse(months, safe=False)


def car_rank(request):
    body = request.json
    id = body.get("id")
    return _car_rank(id)


@lru_cache()
def _car_rank(id):
    # 获取当前日期及1年前的日期
    today = datetime.now().date()
    one_year_ago = today - timedelta(days=365)
    # 设置查询条件
    q = Q(month__gte=one_year_ago.strftime("%Y%m"), month__lte=today.strftime("%Y%m"))
    result = (
        CarSale.objects.filter(q)
        .values("series_id", "series_name")
        .annotate(total_sales=Sum("rank_value"))
        .filter(total_sales__gt=0)
        .order_by("-total_sales")
    )
    sales_rank = next(
        (
            i
            for i, e in enumerate(
                result,
                start=1,
            )
            if e["series_id"] == int(id)
        ),
        -1,
    )
    # ---------
    # 获取当前日期及1年前的日期
    q = Q(
        stime__gte=one_year_ago.strftime("%Y-%m-%d"),
        stime__lte=today.strftime("%Y-%m-%d"),
    )
    result = (
        CarIssue.objects.filter(q)
        .values("series_id", "series_name")
        .annotate(total_issues=Sum("count"))
        .filter(total_issues__gt=0)
        .order_by("-total_issues")
    )
    issue_rank = next(
        (
            i
            for i, e in enumerate(
                result,
                start=1,
            )
            if e["series_id"] == int(id)
        ),
        -1,
    )

    return JsonResponse(dict(sales_rank=sales_rank, issue_rank=issue_rank))


def car_sales_rank(request):
    # 获取请求体中的数据
    body = request.json
    # 获取请求体中的月份
    month = body.get("month")
    # 定义查询条件
    q = Q()
    # 根据月份设置查询条件
    if month == "1y":
        # 获取当前日期及1年前的日期
        today = datetime.now().date()
        one_year_ago = today - timedelta(days=365)
        # 设置查询条件
        q &= Q(
            month__gte=one_year_ago.strftime("%Y%m"), month__lte=today.strftime("%Y%m")
        )
    elif month == "6m":
        # 近半年,即6个月
        today = datetime.now().date()
        half_year_ago = today - timedelta(days=365 // 2)
        # 设置查询条件
        q &= Q(
            month__gte=half_year_ago.strftime("%Y%m"), month__lte=today.strftime("%Y%m")
        )
    else:
        q &= Q(month=month)
    # 统计各个车系一年内的总销量,并按照销量进行排序和排名
    result = (
        CarSale.objects.filter(q)
        .values("series_id", "series_name")
        .annotate(total_sales=Sum("rank_value"))
        .order_by("-total_sales")
    )
    # 对结果进行排名
    result_list = list(result)
    for i, item in enumerate(result_list):
        item["sales_rank"] = i + 1
    # 分页处理数据
    pagesize = body.get("pagesize", 20)
    page_num = body.get("page", 1)
    paginator = Paginator(result_list, pagesize)  # 创建Paginator对象
    page = paginator.get_page(page_num)  # 获取指定页码的数据
    result = list(page.object_list)
    # 获取每个车系的详细信息,并将其添加到结果中
    for i in result:
        car_series = to_dict([CarSeries.objects.get(series_id=i["series_id"])])[0]
        i.update(**car_series)
    # 返回分页后的结果
    return JsonResponse({"total": paginator.count, "records": result})


def car_issue_rank(request):
    body = request.json
    stime = body.get("stime")
    type = body.get("type")
    q = Q()
    if stime == "1y":
        # 获取当前日期及1年前的日期
        today = datetime.now().date()
        one_year_ago = today - timedelta(days=365)
        q &= Q(
            stime__gte=one_year_ago.strftime("%Y-%m-%d"),
            stime__lte=today.strftime("%Y-%m-%d"),
        )
    elif stime == "6m":
        # 近半年,即6个月
        today = datetime.now().date()
        half_year_ago = today - timedelta(days=365 // 2)
        q &= Q(
            stime__gte=half_year_ago.strftime("%Y-%m-%d"),
            stime__lte=today.strftime("%Y-%m-%d"),
        )
    else:
        q &= Q(stime=stime)
    if type:
        q &= Q(type=type)
    # 统计各个车系一年内的总问题数,并按照问题数进行排序和排名
    result = (
        CarIssue.objects.filter(q)
        .values("series_id", "series_name")
        .annotate(total_issues=Sum("count"))
        .order_by("-total_issues")
    )

    # 对结果进行排名
    result_list = list(result)
    for i, item in enumerate(result_list):
        item["issues_rank"] = i + 1

    # 分页处理数据
    pagesize = body.get("pagesize", 20)
    page_num = body.get("page", 1)
    paginator = Paginator(result_list, pagesize)  # 创建Paginator对象
    page = paginator.get_page(page_num)  # 获取指定页码的数据
    result = list(page.object_list)
    for i in result:
        car_series = to_dict([CarSeries.objects.get(series_id=i["series_id"])])[0]
        counter = Counter()
        for x in CarIssue.objects.filter(q, series_id=i["series_id"]).values_list(
            "dxwt", flat=True
        ):
            counter.update(dict([(j["ctiTitle"], j["count"]) for j in x]))
        i["issues"] = counter.most_common(10)
        i.update(**car_series)
    return JsonResponse({"total": paginator.count, "records": result})


def get_detail(request):
    body = request.json
    id = body.get("id")
    o = CarSeries.objects.get(pk=id)
    o = to_dict(o, single=True)
    o["brand"] = to_dict(Brand.objects.get(brand_id=o["brand_id"]), single=True)
    return JsonResponse(o)


def car_360_color_pic(request):
    body = request.json
    id = body.get("id")
    try:
        color_pic_list = requests.get(
            f"https://www.dongchedi.com/motor/pc/car/series/car_360_color_pic?aid=1839&app_name=auto_web_pc&series_id={id}"
        ).json()["data"]["color_pic_list"]
    except:
        color_pic_list = []
    return JsonResponse(color_pic_list, safe=False)


def radar_chart(request):
    body = request.json
    id = body.get("id")
    # 从数据库中读取评分数据
    car_series = CarSeries.objects.get(series_id=id)
    color = "#f4cf63"
    # 转换数据范围
    min_score = 1
    max_score = 500
    scale = 5
    comfort_score = car_series.comfort_score / max_score * scale
    appearance_score = car_series.appearance_score / max_score * scale
    configuration_score = car_series.configuration_score / max_score * scale
    control_score = car_series.control_score / max_score * scale
    power_score = car_series.power_score / max_score * scale
    space_score = car_series.space_score / max_score * scale
    interiors_score = car_series.interiors_score / max_score * scale
    total_score = round(car_series.total_score / max_score * scale, 2)

    # 创建雷达图对象并添加数据
    radar_chart = (
        Radar()
        .add_schema(
            schema=[
                opts.RadarIndicatorItem(name="舒适性", max_=scale),
                opts.RadarIndicatorItem(name="外观", max_=scale),
                opts.RadarIndicatorItem(name="配置", max_=scale),
                opts.RadarIndicatorItem(name="控制", max_=scale),
                opts.RadarIndicatorItem(name="动力", max_=scale),
                opts.RadarIndicatorItem(name="空间", max_=scale),
                opts.RadarIndicatorItem(name="内饰", max_=scale),
            ]
        )
        .add(
            series_name=car_series.series_name,
            data=[
                [
                    round(i, 1)
                    for i in [
                        comfort_score,
                        appearance_score,
                        configuration_score,
                        control_score,
                        power_score,
                        space_score,
                        interiors_score,
                    ]
                ]
            ],
            areastyle_opts=opts.AreaStyleOpts(opacity=0.9, color=color),
            linestyle_opts=opts.LineStyleOpts(color=color),
            label_opts=opts.LabelOpts(position="outside", is_show=total_score != 0),
            symbol=None,
            color="#000",
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title=f"{total_score or '暂无评分'}",
                pos_bottom="45%",
                pos_left="center",
                title_textstyle_opts=opts.TextStyleOpts(
                    color="#000", font_size=30, align="center"
                ),
            ),
            legend_opts=opts.LegendOpts(is_show=False),
        )
    )

    # 生成 HTML 代码并返回到前端
    return HttpResponse(radar_chart.dump_options(), content_type="aplication/json")


def series_sales_trend(request):
    body = request.json
    id = body.get("id")
    # 查询指定车系的月度销量数据
    sales = list(CarSale.objects.filter(series_id=id).order_by("-month")[:12])[::-1]
    months = [sale.month for sale in sales]
    sales_values = [sale.rank_value for sale in sales]
    if not sales_values:
        return JsonResponse({})
    try:
        max_ = max(sales_values)
    except:
        max_ = 0
    # 创建一个 Line 图表对象
    line_chart = Line()

    # 添加 x 轴和 y 轴数据
    line_chart.add_xaxis(months)
    line_chart.add_yaxis(
        "",
        sales_values,
        symbol="circle",
        symbol_size=8,
        itemstyle_opts=opts.ItemStyleOpts(color="#ff7f50"),
        markpoint_opts=opts.MarkPointOpts(
            data=[
                opts.MarkPointItem(type_="max", name="最大值"),
                opts.MarkPointItem(type_="min", name="最小值"),
            ]
        ),
    )

    # 设置全局配置项
    line_chart.set_global_opts(
        title_opts=opts.TitleOpts(title="销量走势图", pos_bottom=0, pos_left="center"),
        xaxis_opts=opts.AxisOpts(
            name="月份",
            axispointer_opts=opts.AxisPointerOpts(is_show=True),
        ),
        yaxis_opts=opts.AxisOpts(
            name="销量",
            axislabel_opts=opts.LabelOpts(formatter="{value} 辆"),
        ),
        legend_opts=opts.LegendOpts(is_show=False),
        visualmap_opts=opts.VisualMapOpts(max_=max_),
    )

    # 设置序列配置项
    line_chart.set_series_opts(
        areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
        linestyle_opts=opts.LineStyleOpts(width=3),
        label_opts=opts.LabelOpts(is_show=False),
    )

    # 生成 HTML 代码并返回到前端
    return HttpResponse(line_chart.dump_options(), content_type="aplication/json")


def series_issue_trend(request):
    body = request.json
    id = body.get("id")
    # 查询指定车系的月度销量数据
    months = list(
        CarIssue.objects.filter(series_id=id, type=1)
        .values_list("stime", flat=True)
        .order_by("-stime")[:12]
    )[::-1]
    months = [i[:-3].replace("-", "") for i in months]
    if not months:
        return JsonResponse({})
    # 创建一个 Line 图表对象
    line_chart = Line()

    # 添加 x 轴和 y 轴数据
    line_chart.add_xaxis(months)
    for type, name in [(1, "质量问题"), (2, "服务问题"), (3, "其他问题")]:
        counts = list(
            CarIssue.objects.filter(series_id=id, type=type)
            .values_list("count", flat=True)
            .order_by("-stime")[:12]
        )[::-1]
        line_chart.add_yaxis(
            name,
            counts,
            symbol="circle",
            symbol_size=8,
            markpoint_opts=opts.MarkPointOpts(
                data=[
                    opts.MarkPointItem(type_="max", name="最大值"),
                    opts.MarkPointItem(type_="min", name="最小值"),
                ]
            ),
        )

    # 设置全局配置项
    line_chart.set_global_opts(
        title_opts=opts.TitleOpts(title="投诉量走势图", pos_bottom=0, pos_left="center"),
        xaxis_opts=opts.AxisOpts(
            name="月份",
            axispointer_opts=opts.AxisPointerOpts(is_show=True),
        ),
        yaxis_opts=opts.AxisOpts(
            name="投诉量",
            axislabel_opts=opts.LabelOpts(formatter="{value}"),
        ),
        legend_opts=opts.LegendOpts(is_show=True, selected_map={"其他问题": False}),
    )

    # 设置序列配置项
    line_chart.set_series_opts(
        areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
        linestyle_opts=opts.LineStyleOpts(width=3),
        label_opts=opts.LabelOpts(is_show=False),
    )

    # 生成 HTML 代码并返回到前端
    return HttpResponse(line_chart.dump_options(), content_type="aplication/json")


def series_sales_rank_trend(request):
    body = request.json
    id = body.get("id")
    # 查询指定车系的月度销量数据
    sales = list(CarSale.objects.filter(series_id=id).order_by("-month")[:12])[::-1]
    months = [sale.month for sale in sales]
    rank_values = [sale.rank for sale in sales]
    if not rank_values:
        return JsonResponse({})
    # 创建一个 Line 图表对象
    line_chart = Line()

    # 添加 x 轴和 y 轴数据
    line_chart.add_xaxis(months)
    line_chart.add_yaxis(
        "",
        rank_values,
        symbol="circle",
        symbol_size=8,
        itemstyle_opts=opts.ItemStyleOpts(color="#ff7f50"),
    )

    # 设置全局配置项
    line_chart.set_global_opts(
        title_opts=opts.TitleOpts(title="销量排名走势图", pos_bottom=0, pos_left="center"),
        xaxis_opts=opts.AxisOpts(
            name="月份",
            axispointer_opts=opts.AxisPointerOpts(is_show=True),
        ),
        yaxis_opts=opts.AxisOpts(
            name="销量排名",
            axislabel_opts=opts.LabelOpts(formatter="第 {value} 名"),
            min_=1,
            is_inverse=True,
        ),
        legend_opts=opts.LegendOpts(is_show=False),
    )

    # 设置序列配置项
    line_chart.set_series_opts(
        linestyle_opts=opts.LineStyleOpts(width=3),
        label_opts=opts.LabelOpts(is_show=True),
    )

    # 生成 HTML 代码并返回到前端
    return HttpResponse(line_chart.dump_options(), content_type="aplication/json")


def issue_timeline_wordcloud(request):
    body = request.json
    id = body.get("id")
    months = list(
        CarIssue.objects.filter(series_id=id, type=1)
        .values_list("stime", flat=True)
        .order_by("-stime")[:12]
    )[::-1]
    months = [i for i in months]  # i[:-3].replace("-", "")
    if not months:
        return JsonResponse({})
    timeline = Timeline().add_schema(is_auto_play=True)
    for month in months:
        # 创建词云图对象
        wordcloud_chart = WordCloud()
        for type, name in [(1, "质量问题")]:
            dxwt = (
                CarIssue.objects.filter(series_id=id, type=type, stime=month)
                .values_list("dxwt", flat=True)
                .order_by("-stime")
                .first()
            )
            words = [(i["ctiTitle"], i["count"]) for i in dxwt]
            # 添加数据并设置全局配置项
            wordcloud_chart.add(
                name,
                words,
                shape="diamond",
            )
        wordcloud_chart.set_global_opts(
            title_opts=opts.TitleOpts(title="质量问题词云图", pos_left="center", pos_top=0),
            legend_opts=opts.LegendOpts(is_show=False),
        )
        timeline.add(wordcloud_chart, month)
    return HttpResponse(timeline.dump_options(), content_type="aplication/json")


def issue_labels(request):
    body = request.json
    id = body.get("id")
    dxwt = list((CarIssue.objects.filter(series_id=id).values_list("dxwt", flat=True)))
    # print(dxwt)
    wt = dict()
    for i in chain(*dxwt):
        if i["ctiChildId"] in wt:
            wt[i["ctiChildId"]]["count"] += i["count"]
        else:
            wt[i["ctiChildId"]] = i
    wt = sorted(list(wt.values()), key=lambda x: x["count"], reverse=True)
    return JsonResponse(wt, safe=False)


def series_price_diff_bar(request):
    # 获取dealer_low_price和official_low_price之间的差值并按total_score倒序排序
    price_diffs = (
        CarSeries.objects.filter(has_dealer_price=True, has_official_price=True)
        .annotate(
            price_diff=F("official_low_price") - F("dealer_low_price"),
        )
        .values_list("series_name", "price_diff")
        .order_by("-price_diff")
    )

    # 取前20个数据进行可视化分析
    price_diffs = price_diffs[:100][::-1]
    # price_diffs.sort(key=lambda x: x[1], reverse=True)

    # 获取车系名称列表和差值列表
    series_names = [i[0] for i in price_diffs]
    price_diff_values = [round(i[1]) for i in price_diffs]

    # 创建柱状图对象并添加数据
    bar = (
        Bar()
        .add_xaxis(series_names)
        .add_yaxis(
            "官方价与经销商报价的差值",
            price_diff_values,
            label_opts=opts.LabelOpts(formatter="{b}"),
        )
        .reversal_axis()
        .set_global_opts(
            title_opts=opts.TitleOpts(title="车系降价排行榜可视化", pos_left="center", pos_top=0),
            legend_opts=opts.LegendOpts(is_show=False),
            datazoom_opts=opts.DataZoomOpts(
                orient="vertical",
                range_start=80,
                range_end=100,
            ),
            xaxis_opts=opts.AxisOpts(name="差价(万元)"),
            yaxis_opts=opts.AxisOpts(
                name="官方价与经销商报价的差值",
                axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
            ),
            tooltip_opts=opts.TooltipOpts(formatter="{b} : 降{c}万"),
        )
    )
    return HttpResponse(bar.dump_options(), content_type="aplication/json")


def brand_distribution(request):
    data = (
        CarSeries.objects.values("brand_name")
        .annotate(total=Count("brand_id"))
        .order_by("-total")
    )[:30]
    brands = [x["brand_name"] for x in data]
    counts = [x["total"] for x in data]

    chart = (
        Pie()
        .add(
            "",
            list(zip(brands, counts)),
            label_opts=opts.LabelOpts(formatter="{b}: {d}%"),
            radius=["40%", "75%"],
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title="汽车品牌数量TOP分布图", pos_left="center", pos_top=0
            ),
            legend_opts=opts.LegendOpts(type_="scroll", pos_left=0, orient="vertical"),
        )
    )

    return HttpResponse(chart.dump_options(), content_type="aplication/json")


def car_series_analysis(request):
    low_price_data = {}
    for i in range(7):
        low_price_data[str(i)] = 0
    for car_series in CarSeries.objects.all():
        if car_series.dealer_low_price is not None:
            if car_series.dealer_low_price < 10:
                low_price_data["0"] += 1
            elif car_series.dealer_low_price < 15:
                low_price_data["1"] += 1
            elif car_series.dealer_low_price < 20:
                low_price_data["2"] += 1
            elif car_series.dealer_low_price < 25:
                low_price_data["3"] += 1
            elif car_series.dealer_low_price < 30:
                low_price_data["4"] += 1
            elif car_series.dealer_low_price < 40:
                low_price_data["5"] += 1
            else:
                low_price_data["6"] += 1

    bar = (
        Bar()
        .add_xaxis(["0-10万", "10-15万", "15-20万", "20-25万", "25-30万", "30-40万", "50万以上"])
        .add_yaxis(
            "车系数量",
            [
                low_price_data["0"],
                low_price_data["1"],
                low_price_data["2"],
                low_price_data["3"],
                low_price_data["4"],
                low_price_data["5"],
                low_price_data["6"],
            ],
            bar_width=50,
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="价格范围数量分布图", pos_left="center", pos_top=0),
            legend_opts=opts.LegendOpts(is_show=False),
            xaxis_opts=opts.AxisOpts(
                name="价格范围",
                axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
            ),
            yaxis_opts=opts.AxisOpts(name="车系数量"),
        )
    )

    return HttpResponse(bar.dump_options(), content_type="aplication/json")



源码获取:

由于篇幅限制,获取完整文章或源码、代做项目的,查看主页【专栏名称】或者【用户名】或者顶部的【选题链接】就可以找到我获取项目源码学习啦~

大家点赞、收藏、关注、评论啦 !

你可能感兴趣的:(毕业设计,biyesheji0002,biyesheji0001,python,课程设计,汽车,爬虫,django)