基于Python+爬虫的房屋租赁数据可视化系统设计与实现
博主介绍✌全网粉丝20W,CSDN全栈领域优质创作者博客之星、掘金/华为云/阿里云等平台优质作者,计算机毕设实战导师。目前专注于大学生项目实战开发,讲解,毕业答疑辅导欢迎高校老师/同行前辈交流合作✌主要服务内容免费功能设计、选题定题、开题报告、任务书、程序开发、论文编写和辅导、论文降重、程序讲解、答辩辅导等欢迎咨询~ 精彩专栏 推荐订阅计算机毕业设计精品项目案例持续更新值得收藏✅2026-2027年计算机毕业设计选题推荐计算机专业毕业设计题目大全✅全网最全计算机毕业设计选题推荐计算机毕设选题指导及避坑指南✅文末获取源码数据库文档感兴趣的可以先收藏起来还有大家在毕设选题项目以及论文编写等相关问题都可以和学长沟通希望帮助更多的人文章目录一.项目概述二.开发技术栈2.1 基础环境2.2 核心技术架构三.系统分析3.1 需求分析与角色划分3.1.1 总体功能需求3.1.2 角色划分3.1.3 各角色细分功能需求3.2 用例设计3.3 系统功能模块设计四.数据设计五.部分效果展示5.1管理员功能实现效果5.2用户功能实现效果5.3可视化看板实现效果六.部分代码实现6.1 项目开发核心技术难点说明6.2 基于 Scrapy Requests 实现数据采集核心代码源码及文档获取一.项目概述房屋租赁信息在网络平台上的聚合发布使得租赁数据呈现出来源多、更新快、结构与文本并存等特征。围绕这类数据本文以基于Python的房屋租赁数据可视化系统设计与实现为目标面向大数据管理系统的应用场景构建一套覆盖采集、存储、展示与交互的可视化分析体系。本文以Python为核心开发语言结合数据采集与协同推荐算法思路对房源信息与外部租赁数据进行统一组织在数据层以结构化存储承载房源、租赁、公告、交流与留言等信息并在此基础上搭建可视化看板形成面向多维指标的统计展示与趋势分析。系统实现后前台用户能够围绕房源信息、外部租赁信息、公告信息与交流互动完成常用操作后台管理员能够对用户、房屋类型、房源信息、租赁数据、外部租赁信息、公告信息、论坛交流、敏感词、在线留言、轮播图与个人中心进行集中管理。通过看板对户型、楼层、小区、用户租赁次数、房屋类型租赁占比、房屋类型收益、小区价格、朝向与城市等维度进行展示提升了租赁数据的可读性与管理效率。二.开发技术栈2.1 基础环境开发语言后端 Python前端 Vue数据库MySQL 5.7保障数据存储与版本兼容性项目构建工具Python pip、前端 npm开发工具PyCharm、VS Code、Navicat2.2 核心技术架构前端框架采用 Vue 开发页面实现交互展示与功能操作。数据采集层基于 Requests、Scrapy 编写爬虫自动化采集网络数据。数据处理层依托 Python、Pandas、NumPy 完成数据清洗、运算与规整。服务应用层后端使用 Flask 搭建 Web 服务提供接口支撑前端调用。数据存储层采用 MySQL 5.7 持久化存储采集、加工后的业务数据。三.系统分析3.1 需求分析与角色划分3.1.1 总体功能需求本系统分为前台用户端与后台管理员端两大体系面向租房场景实现全流程线上服务。前端提供账号管理、房源浏览检索、收藏评论、租赁申请、论坛互动、在线留言等功能依托算法实现房源智能推荐后端支持爬虫数据采集与清洗、房源/用户/内容管控、租赁申请审核、留言回复、系统配置、日志记录并通过数据可视化大屏直观展示房源多维度统计数据同时具备完整权限校验与安全管控能力满足日常运营、数据管理与运维审计需求。3.1.2 角色划分结合系统业务与使用人群划分两类核心角色普通用户、系统管理员两类角色权限相互隔离各司其职覆盖平台使用、运营、数据维护全场景。3.1.3 各角色细分功能需求1管理员功能需求1.账号安全实现后台账号登录、身份权限校验、安全退出操作。2.数据采集运维启停爬虫任务完成房源数据爬取、去重、补全、纠错、格式标准化等清洗工作。3.房源管理对房源信息进行编辑、删除、上下架操作处置违规房源。4.业务审核查看并处理用户提交的房源租赁申请。5.用户管控查看全体用户列表管控违规账号追溯用户行为数据。6.内容管理审核房源评论、论坛帖子删除违规内容置顶精华帖、封禁违规用户。7.留言处理查看用户咨询、建议与投诉留言在线回复并标记处理状态。8.数据可视化依托可视化大屏统计展示房源区域、价格、户型、面积等多维度数据。9.系统运维查看系统运行、管理员操作、用户异常行为等各类日志配置平台名称、公告、轮播2用户功能需求1.账号管理支持通过账号或手机号进行注册、登录及密码找回并可自主修改个人资料。2.房源浏览可查看首页公告及算法推荐的房源支持多条件筛选与检索并能查看房源的详细信息包括户型、位置及配套设施。3.房源操作可收藏心仪的房源并支持查看与取消收藏能够发布房源评论、为评论点赞并浏览其他用户的评价。4.业务申请支持在线提交房源租赁申请。5.社区互动可在论坛中发布帖子、提出问题、回复内容并浏览与点赞热门话题。6.意见反馈可提交咨询、建议或投诉留言并能查看个人的历史留言记录。7.个人中心统一管理个人信息、收藏的房源、发布的评论、帖子及留言数据。帖子及留言数据。3.2 用例设计结合业务需求绘制管理员用例图、用户用例图清晰定义各角色可执行操作3.3 系统功能模块设计功能模块设计以权限划分为主线前台侧围绕信息浏览与互动参与组织模块后台侧围绕数据维护与内容治理组织模块。为了使模块关系更清晰系统总体结构以数据采集层—数据处理层—存储结构层—业务服务层—展示交互层的思路组织并以看板作为展示交互层的重要组成。系统总体结构图如图所示。四.数据设计系统需要以存储结构承载运行所需的多类数据对象并为业务管理与可视化统计提供统一的数据基础。概念模型的作用在于抽象系统所涉及的实体、属性与关联关系使后续的数据表设计能够有清晰的依据。其中实体分析用于抽象系统中需要长期存储与维护的信息对象并明确实体之间的关联关系。社区在本系统中用户信息、房源信息、房屋类型与租赁记录构成核心实体公告信息、论坛交流、在线留言与评论信息构成内容实体配置、敏感词与收藏等构成辅助实体。用户信息相关实体关系如图所示。房源与租赁相关实体关系如图所示。系统整体实体关系如图所示。五.部分效果展示5.1管理员功能实现效果管理员进入系统前需要完成身份校验。在登录界面中管理员输入用户名与密码完成登录操作系统对输入信息进行校验并在通过后进入后台首页如图所示。管理员进入后台后可在系统首页查看管理入口并对用户、房屋类型、房源信息、房源租赁、安微租房、公告信息、论坛交流、敏感词、在线留言、轮播图管理与个人中心等功能进行操作如图所示。管理员点击用户管理后可按条件检索用户信息并对用户账号、姓名、手机号等数据进行维护实现新增、修改与删除等操作如图所示。管理员点击房源信息管理后可对房屋编号、楼号、类型、朝向、位置、面积、价格、状态与发布时间等信息进行维护同时支持按条件查询与列表管理如图所示。管理员在房屋类型管理中可维护房屋类型数据并在租赁与房源维护时形成一致的分类口径同时在租房模块中可对外部租赁信息进行管理与查看以便与平台内房源信息形成互补如图所示。5.2用户功能实现效果用户首次使用系统时需要完成注册流程。注册界面用于录入用户账号、密码、姓名、性别、手机号与头像等信息系统对信息完整性进行校验并在通过后写入存储结构使用户具备后续登录与使用权限如图所示。用户注册完成后进入登录界面输入账号与密码完成登录。登录成功后用户可访问首页、房源信息、安微租房、公告信息、论坛交流、在线留言与个人中心等功能入口并围绕房源浏览、交流参与与收藏管理完成日常操作如图所示。5.3可视化看板实现效果系统提供可视化看板用于对租赁数据进行多维展示通过统一的统计口径输出图形化结果使用户与管理者能够在同一视角下理解数据分布与差异。看板整体展示界面如图所示。六.部分代码实现6.1 项目开发核心技术难点说明难点 1房源爬虫数据采集与清洗处理基于 Scrapy 实现多页面分层爬取兼容多种 URL 格式与运行环境完成网页 HTML 标签过滤、空值容错同时适配多类数据库并做数据表前置校验保障采集数据规范可用。难点2房源多维度数据可视化大屏构建基于清洗后的海量房源数据对房源价格、区域、户型、面积、建成年代等多维度指标进行统计聚合。结合Vue可视化组件动态渲染图表解决数据杂乱、统计维度多、实时刷新困难的展示难题。6.2 基于 Scrapy Requests 实现数据采集核心代码# 导入所需第三方库与模块importreimportrandomimportplatformimportjsonimportosimporttimeimportemojiimportrequestsimportpymysqlimportpymssqlfromurllib.parseimporturlparseimportscrapy# 导入当前爬虫项目的数据实体类from..itemsimportxiangmuItemclassXiangmuSpider(scrapy.Spider): 房源数据爬虫 功能爬取列表页房源基础信息再进入详情页抓取作者等信息 支持 MySQL / SQL Server 双数据库适配、数据表存在性校验、URL 补全、HTML 标签过滤 # 爬虫唯一标识名称启动爬虫命令scrapy crawl xiangmuSpidernamexiangmuSpider# 多起始地址用分号 ; 分隔自动拆分spider_urlhttps://url网址start_urlsspider_url.split(;)# 全局变量协议头、域名用于补全相对路径URLprotocolhostnamedef__init__(self,*args,**kwargs): 爬虫初始化构造方法 super().__init__(*args,**kwargs)defparse(self,response): 列表页解析入口 1. 解析域名与协议用于拼接完整URL 2. 数据库校验若数据表已存在则直接终止本次爬取 3. 遍历列表数据提取基础字段并跳转详情页 :param response: 列表页响应对象 :return: 详情页请求对象 # 解析起始URL拆分协议、主机名url_parse_resulturlparse(self.spider_url)self.protocolurl_parse_result.scheme self.hostnameurl_parse_result.netloc# 根据操作系统判断执行逻辑sys_platformplatform.system().lower()ifsys_platformin(linux,windows):# 建立数据库连接db_connself.db_connect()db_cursordb_conn.cursor()# 校验目标数据表是否已存在ifself.table_exists(db_cursor,xiangmu)1:# 表已存在关闭数据库资源执行临时数据逻辑并终止爬取db_cursor.close()db_conn.close()self.temp_data()return# 定位列表页所有房源节点item_listresponse.css(ul.subject-list li.subject-item)# 遍历每一条房源数据fornodeinitem_list:# 实例化Item对象用于封装爬取字段itemxiangmuItem()# 1. 抓取来源链接source_urlnode.css(div.pic a.nbg::attr(href)).extract_first()# 去除HTML标签与空白字符item[laiyuan]self.remove_html(source_url)# 补全相对URL为完整可访问地址item[laiyuan]self.complete_url(item[laiyuan])# 2. 抓取封面图地址cover_imgnode.css(div.pic a.nbg img::attr(src)).extract_first()item[fengmian]self.remove_html(cover_img)# 3. 抓取房源简短名称/标题titlenode.css(div.info h2 a::attr(title)).extract_first()item[xiaoshuoming]self.remove_html(title)# 详情页URL处理detail_urlnode.css(div.pic a.nbg::attr(href)).extract_first()detail_urlself.complete_url(detail_url)# 同步更新来源地址为详情页地址item[laiyuan]detail_url# 发起详情页请求将当前已抓取字段通过meta传递到详情解析函数yieldscrapy.Request(urldetail_url,meta{fields:item},callbackself.detail_parse,dont_filterTrue# 关闭去重保证正常抓取)defdetail_parse(self,response): 详情页解析函数 抓取作者信息整合所有字段后交付Pipeline入库 :param response: 详情页响应对象 :return: 封装完成的Item数据 # 接收列表页传递过来的Item数据itemresponse.meta[fields]try:# 抓取作者信息author_textresponse.css(div#info span a::text).extract_first()# 清洗HTML、空格、特殊符号item[zuozhe]self.remove_html(author_text)exceptExceptionase:# 异常捕获作者字段抓取失败则置空不中断整体爬取self.logger.warning(f作者信息抓取异常:{str(e)})item[zuozhe]# 将完整Item交给Scrapy管道进行数据持久化yielditemdefremove_html(self,html_str): 工具方法清除HTML标签、首尾空白字符 :param html_str: 原始带标签字符串 :return: 纯文本内容 ifnothtml_str:return# 正则匹配所有HTML标签并替换为空html_patternre.compile(r[^],re.S)clean_texthtml_pattern.sub(,html_str)# 去除首尾空格、换行returnclean_text.strip()defcomplete_url(self,raw_url): 工具方法统一补全相对URL为完整URL修复原代码重复拼接逻辑 :param raw_url: 原始相对链接 :return: 完整HTTP/HTTPS链接 ifnotraw_url:return# 已为完整链接直接返回ifraw_url.startswith((http://,https://)):returnraw_url# 协议相对链接 //xxx.comifraw_url.startswith(//):returnf{self.protocol}:{raw_url}# 站点内相对链接 /xxx/xxxifraw_url.startswith(/):returnf{self.protocol}://{self.hostname}{raw_url}# 其他情况直接返回原字符串returnraw_urldefdb_connect(self): 数据库连接方法 读取Scrapy配置文件参数支持 MySQL / SQL Server 两种数据库 :return: 数据库连接对象 # 读取配置文件中的数据库类型、地址、端口、账号、密码db_typeself.settings.get(TYPE,mysql)hostself.settings.get(HOST,localhost)portint(self.settings.get(PORT,3306))userself.settings.get(USER,root)passwordself.settings.get(PASSWORD,123456)# 优先读取实例传参的数据库名无则读取配置文件try:db_nameself.databaseNameexceptAttributeError:db_nameself.settings.get(DATABASE,)# 根据数据库类型创建连接ifdb_typemysql:connpymysql.connect(hosthost,portport,dbdb_name,useruser,passwdpassword,charsetutf8)else:connpymssql.connect(hosthost,useruser,passwordpassword,databasedb_name)returnconndeftable_exists(self,cursor,table_name): 工具方法判断数据库中指定数据表是否存在 :param cursor: 数据库游标对象 :param table_name: 待校验表名 :return: 1表存在 0表不存在 # 查询当前库下所有数据表cursor.execute(SHOW TABLES;)# 提取所有表名all_tablescursor.fetchall()table_listre.findall(r(.*?),str(all_tables))table_list[t.replace(,)fortintable_list]return1iftable_nameintable_listelse0deftemp_data(self): 临时数据处理逻辑原代码预留方法业务自定义 数据表已存在时执行此方法可自行扩展逻辑 self.logger.info(目标数据表已存在跳过新一轮爬取执行临时数据逻辑)源码及文档获取文章下方名片联系我即可~大家点赞、收藏、关注、评论啦 、查看获取联系方式精彩专栏推荐订阅在下方专栏最新计算机毕业设计选题篇-选题推荐小程序毕业设计精品项目案例-200套Java毕业设计精品项目案例-200套Python毕业设计精品项目案例-200套大数据毕业设计精品项目案例-200套如果大家有任何疑虑欢迎在下方位置详细交流。

相关新闻

UDS 操作循环:DTC状态机背后的驾驶周期逻辑

UDS 操作循环:DTC状态机背后的驾驶周期逻辑

1. 什么是UDS操作循环?当你开车时,ECU(电子控制单元)就像车辆的"大脑",持续监控着各个系统的状态。而UDS(统一诊断服务)中的操作循环,就是这些监控行为的"心跳节奏&q…

2026/7/15 20:20:11阅读更多 →
蓝牙协议栈与核心规范:从广播到连接的通信基石

蓝牙协议栈与核心规范:从广播到连接的通信基石

1. 蓝牙技术基础:从广播到连接的通信基石 想象一下你刚买了一套无线键鼠套装,拆开包装后只需要按下键盘底部的配对按钮,电脑屏幕上就立刻弹出了连接提示——这种看似简单的"魔法"背后,正是蓝牙协议栈在发挥作用。作为现…

2026/7/15 20:20:11阅读更多 →
《机械工厂6S白皮书03|第2章 诊断核心:四步熵增定位法——穿透表面乱象,精准锁定机械车间混乱的真实病灶》

《机械工厂6S白皮书03|第2章 诊断核心:四步熵增定位法——穿透表面乱象,精准锁定机械车间混乱的真实病灶》

6S管理实战专栏|机械工厂精益6S白皮书【第3篇/共9篇】本文为《机械工厂6S精益落地实战白皮书》全系列连载【第2章 诊断核心】,全文2万多字,按章节持续更新中......第2章 诊断核心:四步熵增定位法——穿透表面乱象,精准…

2026/7/15 20:20:11阅读更多 →
Kubernetes 监控实战:使用 Alertmanager 实现邮件告警、分组路由与告警抑制

Kubernetes 监控实战:使用 Alertmanager 实现邮件告警、分组路由与告警抑制

前言在前面的监控实践中,我们已经通过 ServiceMonitor 让 Prometheus 抓取了 NVIDIA DCGM Exporter 和 vLLM 的指标,并使用 PrometheusRule 编写了 GPU 与推理服务告警规则。但是,Prometheus 负责的是“判断告警是否成立”,并不负…

2026/7/15 23:30:35阅读更多 →
OpenAMP 架构深度剖析:remoteproc 与 RPMsg 在 FreeRTOS+Linux 双系统通信中的协作机制

OpenAMP 架构深度剖析:remoteproc 与 RPMsg 在 FreeRTOS+Linux 双系统通信中的协作机制

OpenAMP 架构深度剖析:remoteproc 与 RPMsg 在 FreeRTOSLinux 双系统通信中的协作机制 一、多核异构系统的通信地狱——当 Cortex-A 的 Linux 遇上了 Cortex-M 的裸机 现代边缘 SoC(如 STM32MP1、i.MX 8M Mini)普遍集成 Cortex-A Cortex-M…

2026/7/15 23:30:35阅读更多 →
【沐风老师】3DMAX编织建模插件:从可编辑多边形到艺术品的进阶指南

【沐风老师】3DMAX编织建模插件:从可编辑多边形到艺术品的进阶指南

1. 为什么可编辑多边形是编织建模的最佳载体第一次接触3DMAX编织建模时,我也曾疑惑:为什么教程都强调要使用可编辑多边形?直到亲手对比测试才发现,这简直是天壤之别。想象你要编织一个竹篮,用原始圆柱体和用可编辑多边…

2026/7/15 23:30:35阅读更多 →
NCNN 多线程推理的负载均衡调度对决:按输出通道均分与按计算量均分两种策略的基准测试报告

NCNN 多线程推理的负载均衡调度对决:按输出通道均分与按计算量均分两种策略的基准测试报告

NCNN 多线程推理的负载均衡调度对决:按输出通道均分与按计算量均分两种策略的基准测试报告 一、线程闲置的真相——当 4 核 CPU 的推理吞吐量还不如单核时发生了什么 在 NCNN 的边缘推理部署中,开启多线程后延迟反而恶化的情况并不少见。以 RK3588 上的 …

2026/7/15 23:30:35阅读更多 →
TFLite 异步推理流水线架构:用 C++ future/promise 榨干边缘 SoC 的每一毫秒计算力

TFLite 异步推理流水线架构:用 C++ future/promise 榨干边缘 SoC 的每一毫秒计算力

TFLite 异步推理流水线架构:用 C future/promise 榨干边缘 SoC 的每一毫秒计算力 一、同步推理的死锁陷阱——当预处理阻塞了下一帧 在边缘 AI 部署场景中,推理引擎的吞吐量瓶颈往往不在模型本身,而在数据流水线的串行阻塞。以 TFLite 在 ARM…

2026/7/15 23:30:35阅读更多 →
GPT-5.6模型发布:三箭齐发策略与API接入实战指南

GPT-5.6模型发布:三箭齐发策略与API接入实战指南

OpenAI 在 2026 年 7 月 9 日正式发布了 GPT-5.6 系列模型,这次采用了"三箭齐发"的产品策略,推出了旗舰型号 Sol、平衡型 Terra 和经济型 Luna 三个不同定位的模型。这次发布不仅是性能的全面提升,更重要的是在效率、成本控制和实际…

2026/7/15 23:25:35阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/15 6:42:19阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/15 6:12:45阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/15 10:54:00阅读更多 →
AI框架决定企业AI能走多远

AI框架决定企业AI能走多远

企业AI建设的第一性原理 企业搞AI,最关键的决定是什么?不是选哪家大模型,不是先做哪个场景,不是招多少AI人才——而是选哪个AI开发框架。 为什么?因为框架决定了企业AI能力的"天花板"。选对了框架&#xff0…

2026/7/15 0:01:30阅读更多 →
Java企业为什么需要AI框架

Java企业为什么需要AI框架

Java企业在AI时代的尴尬处境 Java是全球企业级应用开发的主流语言——全球超过一半的企业系统跑在Java上。但在AI浪潮面前,很多Java企业感到尴尬:大模型的接口是各种语言的,AI开发社区以其他语言为主流,似乎Java在AI时代"掉队…

2026/7/15 0:01:30阅读更多 →
CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

1. 项目概述:为什么需要关注CC3230x的SD主机、定时器与低功耗?在物联网和嵌入式设备开发领域,我们常常面临一个核心矛盾:设备需要具备强大的连接能力、可靠的数据存储和实时控制功能,同时又必须严格控制功耗以延长电池…

2026/7/15 0:01:30阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/15 15:50:47阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/15 8:52:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/15 14:06:23阅读更多 →