当前位置:   article > 正文

大数据毕业设计:python汽车数据爬取分析可视化系统 懂车帝 Django框架 vue框架✅_基于scrapy的汽车信息获取系统

基于scrapy的汽车信息获取系统

博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业✌感兴趣的可以先收藏起来,点赞、关注不迷路✌

毕业设计:2023-2024年计算机毕业设计1000套(建议收藏)

毕业设计:2023-2024年最新最全计算机专业毕业设计选题汇总

1、项目介绍

技术栈:
Python语言、Django框架 、MySQL数据库、Vue框架、Scrapy爬虫、Echarts可视化、懂车帝网数据

2、项目界面

(1)汽车数据、条件筛选汽车
在这里插入图片描述

(2)汽车数据详情页
在这里插入图片描述

(3)销量排行榜

在这里插入图片描述

(4)差评榜单

在这里插入图片描述
(5)可视化分析

在这里插入图片描述

(6)后台数据管理
在这里插入图片描述

(7)数据采集
在这里插入图片描述

3、项目说明

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

该系统主要包含以下几个模块:
1.Scrapy爬虫:使用Scrapy框架抓取了“懂车帝”网站的汽车及销量数据,以及“车质网”的汽车投诉数据,并将这些数据存储进MySQL数据库中,为后续的展示和查询提供了数据基础。

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

这个项目使用了很多技术组合,下面是各个部分所用到的主要技术:

  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 接口设计等相关工作。

各模块功能实现:

  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实现表单和对话框等交互组件,提高系统的易用性。

4、核心代码


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 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)

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")
  • 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
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/353374
推荐阅读
相关标签