Scrapy + Django爬虫可视化项目实战(一)

目录

一、项目介绍

(一) 项目背景

(二) 项目介绍

二、系统实现

(一) 爬虫

1. 实现步骤

一、爬取字段

二、分析页面

三、具体实现

2. 爬虫结果


系列文章

Python升级打怪—Django入门

Python升级打怪—Scrapy零基础小白入门

实现技术

  • Scrapy
  • Django
  • Echarts

一、项目介绍

(一) 项目背景

在信息技术高速发展的今天,数据已经成为决策的重要依据。旅游业作为服务性行业的重要支柱,其数据资源尤为丰富。去哪儿网作为中国领先的在线旅游平台,拥有大量的景点数据,这些数据对于分析旅游市场动态、游客行为以及景点管理策略等具有极高的价值。通过对去哪儿网景点数据的分析,我们可以了解游客的偏好、旅游市场的趋势以及景点的竞争力等信息。同时,数据可视化可以将复杂的数据信息以直观、易懂的方式呈现出来,有助于决策者更好地理解数据背后的含义

(二) 项目介绍

本项目采用Scray框架爬取去哪儿网的景点数据以及景点的评论数据,将爬取到的数据存储为csv,再通过Django Web框架技术将数据存储到Mysql,然后通过编写接口、分析数据,通过接口将数据返回前端,前端结合Echarts制作可视化表

二、系统实现

(一) 爬虫

爬取网址:去哪儿网

1. 实现步骤

一、爬取字段

本项目爬取的数据分为两部分:【景点数据、景点评论数据】,并将爬取的数据分别存入两个CSV文件中

景点字段

# 景点名称
name = scrapy.Field()
# 景点价格
price = scrapy.Field()
# 所属城市
province = scrapy.Field()
# 评级
star = scrapy.Field()
# 地址
address = scrapy.Field()
# 详情url
detail_url = scrapy.Field()
# 评论数
comment_total = scrapy.Field()
# 短评
short_intro = scrapy.Field()
# 详评
detail_intro = scrapy.Field()
# 封面
cover = scrapy.Field()
# 销售额
sale_count = scrapy.Field()
# 地区
districts = scrapy.Field()
# 评分
score = scrapy.Field()

景点评论字段

# 景点名称
travel_name = scrapy.Field()
# 内容
content = scrapy.Field()
# 评论时间
date = scrapy.Field()
二、分析页面

以地区为北京的景点为例子,搜索结果如下

景点数据

通过分析页面得出,景点数据是通过发送Ajax请求获得,那么我们就不用解析页面,可以直接通过请求获取景点数据即可

当然请求里的景点数据有些字段是没有的,需要我们进入到景点的详情页去爬取

第一个景点:故宫博物院详情页路由

故宫博物院门票,故宫博物院门票预订,故宫博物院门票价格,去哪儿网门票

第二个景点:八达岭长城详情页路由

八达岭长城门票,八达岭长城门票预订,八达岭长城门票价格,去哪儿网门票

通过对比路由地址得出

景点的详情页路由是由基本的路由地址加上景点Id拼接得出,那么在Ajax请求的景点数据字段就有景点id,
那么如果获取指定的景点详情地址,就可以通过拼接该景点id获得

进入到景点详情页,解析页面,获取景点的【评分、评论人数、评论数据

这里我们可以通过Xpath解析页面 ,获取景点的评分以及评论人数

景点评论

请求URL示例:https://piao.qunar.com/ticket/detailLight/sightCommentList.json?sightId=38170&index=2&page=2&pageSize=10&tagType=0

景点评论数据也是通过发送Ajax请求获取,但不同的是需要携带上景点的id,在这个景点的id不同于进入景点详情页的景点id,它是在景点详情页中的,在查看网页源代码中,我们也是可以找到这个id的,后面我们就可以通过页面解析得到这个id,再拼接请求地址就可以去获取景点评论数据了

三、具体实现

基础的项目搭建就不在赘述,如有不懂的请看系列文章

爬虫前必看

  1. 一定要设置休眠时间!!!这对网站和你都好
  2. 因为爬取的数据量很大,爬虫时间会很长,大家可以根据自己的需求合理改造,比如选择合适时间爬取、爬取少量城市或每个城市爬取1-2页数据等

问题一:爬取的数据(景点数据、评论数据)分开存储

可以通过scrapy框架提供的pipelines文件中解决,根据定义数据结构存储到指定文件中,还可以进行数据处理等等操作

问题二:爬取数据层层嵌套

通过前面的页面分析,我们所要爬取的数据层层嵌套,爬取起来比较麻烦,当然也是难不倒我们的

首先准备基础数据

name = "Quanar"
allowed_domains = ["piao.qunar.com"]
start_urls = ["https://piao.qunar.com/daytrip/list.htm"]# 所要爬取景点的城市
province_list = ['北京', '天津', '河北', '山西', '内蒙古', '辽宁', '吉林', '黑龙江', '上海', '江苏','浙江', '安徽', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东','广西', '海南', '重庆', '四川', '贵州', '云南', '西藏', '陕西', '甘肃','青海', '宁夏', '新疆', '台湾', '香港', '澳门']# 城市景点列表的ajax请求网址:keyword:城市名称 page:第几页 sort:pp=》按人气排名
url = 'https://piao.qunar.com/ticket/list.json?keyword=%s&region=&from=mpl_search_suggest&page=%s&sort=pp'
# 景点url
travel_url = 'https://piao.qunar.com/ticket/detail_%s.html'
# 景点评论url
comment_url = 'https://piao.qunar.com/ticket/detailLight/sightCommentList.json?sightId=%s&index=1&page=%s&pageSize=10&tagType=0'

发起请求,获取指定城市的指定页的景点数据

def start_requests(self):# 遍历每个城市列表for index, province in enumerate(self.province_list, 1):# 每个城市爬取 多少页 数据for page in range(5):yield Request(url=(self.url % (province, page)), callback=self.parse_travel_list,meta={"province": province})return

解析景点数据,拼接景点详情页地址,继续发起请求

# 解析单个城市里的多个景点数据
def parse_travel_list(self, response):# 城市名称province = response.meta['province']# 城市景点列表travel_list = response.json()['data']['sightList']for index, travel in enumerate(travel_list):try:travel_item = TravelItem()# 景点名称name = travel['sightName']print("正在爬取该页 %s 条数据,景点名称为:%s" % (str(index + 1), name))# 门票价格try:price = travel['qunarPrice']except:price = 0# 有点景点可能没有评等级,所以需要判断一下try:star = travel['star']except:star = '未评'# 详细地址address = travel['address']# 短评short_intro = travel['intro']# 封面cover = travel['sightImgURL']# 销售额sale_count = travel['saleCount']# 地区districts = travel['districts']# ======================================= 详情爬虫# 景点idsightId = travel['sightId']# 详情地址detail_url = self.travel_url % sightIdtravel_item['name'] = nametravel_item['province'] = provincetravel_item['price'] = pricetravel_item['star'] = startravel_item['address'] = addresstravel_item['short_intro'] = short_introtravel_item['cover'] = covertravel_item['sale_count'] = sale_counttravel_item['districts'] = districtstravel_item['detail_url'] = detail_url# 生成新的Request,并传递给下一个解析函数yield scrapy.Request(detail_url, callback=self.parse_travel_details, meta={'travel_item': travel_item})returnexcept:continue

解析页面,获取景点的评分以及评论人数、请求景点评论所需的id,拼接获取景点评论的url,继续发起请求

    # 解析单个景点里的详情def parse_travel_details(self, response):travel_item = response.meta['travel_item']name = travel_item['name']travel_detail_xpath = Selector(response)# 评论总数comment_total = travel_detail_xpath.xpath('//span[@class="mp-description-commentCount"]/a/text()')[0].get().replace('条评论', '')# 详情介绍detail_intro = travel_detail_xpath.xpath('//div[@class="mp-charact-desc"]//p/text()').get()# 评分score = travel_detail_xpath.xpath("//span[@id='mp-description-commentscore']/span/text()").get()if not score:score = 0else:score = score[0]travel_item['comment_total'] = comment_totaltravel_item['detail_intro'] = detail_introtravel_item['score'] = score# print("爬取存储的travel_item:%s" % travel_item)yield travel_item# ======================================= 评论爬虫data_sight_id = travel_detail_xpath.xpath('//div[@class="mp-tickets-new"]/@data-sightid')[0].get()comment_url = self.comment_url % (data_sight_id, 1)# 生成新的Request,并传递给下一个解析函数yield scrapy.Request(comment_url, callback=self.parse_comments, meta={"name": name})

解析评论数据

# 解析单个景点里的评论
def parse_comments(self, response):try:print("正在爬取%s的评论数据" % response.meta['name'])comment_json = response.json()['data']['commentList']name = response.meta['name']for comment in comment_json:item = CommentItem()if comment['content'] != '用户未点评,系统默认好评。':item['travel_name'] = nameitem['content'] = str(comment['content'])item['date'] = comment['date']yield itemexcept:return

2. 爬虫结果

整个爬虫代码结束,让我们看看爬取到结果

爬取1958个景点数据

每个景点对应评论6213

好的,爬虫部分实现,接下来就是项目可视化,请看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS(五)——CSS Fonts(字体)

CSS 字体 CSS字体属性定义字体,加粗,大小,文字样式。 CSS字型 在CSS中,有两种类型的字体系列名称: 通用字体系列 - 拥有相似外观的字体系统组合(如 "Serif" 或 "Monospace"&#x…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day5 全网最快最全

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我会…

hadoop学习(一)

一.hadoop概述 1.1hadoop优势 1)高可靠性:Hadoop底层维护多个数据副本,即使Hadoop某个计算元素或存储出现故障,也不会导致数据的丢失。 2)高扩展性:在集群间分配任务数据,可方便扩展数以千计…

SPSS个人版是什么软件

SPSS是一款数据统计、分析软件,它由IBM公司出品,这款软件平台提供了文本分析、大量的机器学习算法、数据分析模型、高级统计分析功能等,软件易学且功能非常强大,可以使用SPSS制作图表,例如柱状、饼状、折线等图表&…

【Drools】(一)基于业务需求动态生成 DRT 规则模板:事实与动作定义详解

(一)基于业务需求动态生成 DRT 规则模板:事实与动作定义详解 背景 在业务规则管理中,DRT 文件(Drools Rule Template)用于定义和重用规则模板,这些模板可以动态地根据实际业务需求进行填充和生…

Android 10.0 Launcher 启动流程

在前面SystemUI启动流程中说到,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中…

前端创建仓库的详细步骤

第一步点击号新建仓库 第二步输入完仓库名称路径会自己出来然后点击创建 第三步在自己创建的文件夹右键点击GIt Bash Here 第四步把我框的这些一个一个的输在Git Bash Here中每输入一个回车一个 第五步全部输入完以后CtrlF5自动刷新下就好了 然后文件夹就会有.git了

机器视觉12-相机

相机 作用: 工业相机 是 机器视觉系统 的重要组成部分 最本质的功能就是通过CCD或CMOS成 像传感器将镜头产生的光信号转变为 有序的电信号,并将这些信息通过相 应接口传送到计算机主机 工业相机分类 目前业内没有对相机进行明确的分类定义, 以下分类是…

Python 学习中的 API,如何调用API ?

1.1 API的定义 API,全称是Application Programming Interface(应用程序编程接口)。它是一组定义好的协议和工具,用于在软件应用程序之间进行通信。API可以简化软件开发,使不同的应用程序能够相互协作。它是软件开发中…

数字车间与智能工厂:区别、联系与制造业的未来转型

数字车间和智能工厂在制造业中扮演着重要角色,它们之间存在明显的区别和紧密的联系。以下是对两者区别和联系的详细阐述: 一、区别 定义与范围 数字车间:数字车间是指通过信息化技术、智能化装备和数据化管理等手段,实现生产过程全…

【Python系列】Python 程序的优雅退出:使用`sys.exit()`控制程序终止

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

笔记本电脑怎么录屏?5个小技巧(2024最全)

在今天,录屏功能已经不再是专业人士的专属,而是融入了普通人的日常生活与工作之中。想要记录游戏的精彩瞬间、分享软件的操作教程,或是保存屏幕上的重要信息,录屏都能帮你一键搞定。那么,对于我们这些日常使用笔记本电…

初始K8s

K8S 基本概念: K8S 的全称为 Kubernetes (K12345678S),PS:“嘛,写全称也太累了吧,不如整个缩写”。 作用: 用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。 可以理解成…

火狐浏览器怎么切换ip:详细步骤与注意事项

随着互联网的飞速发展,网络环境的复杂性和安全性问题日益凸显。对于需要保护个人隐私、突破地域限制或进行网络测试的用户来说,切换IP地址成为了一项重要的技能。火狐浏览器,作为一款备受欢迎的开源浏览器,凭借其强大的自定义功能…

【计算机网络】TCP和UDP的封装以及案例

TCP和UDP的封装以及案例 背景知识TCP实现UDP实现封装Network用NetWork再次实现TCP和UDP小知识点 背景知识 TCP:传输控制协议(Transmission Control Protocol) UDP:用户数据报协议 (User Datagram Protocol&#xff09…

AI的欺骗游戏:揭示多模态大型语言模型的易受骗性

人工智能咨询培训老师叶梓 转载标明出处 多模态大型语言模型(MLLMs)在处理包含欺骗性信息的提示时容易生成幻觉式响应。尤其是在生成长响应时,仍然是一个未被充分研究的问题。来自 Apple 公司的研究团队提出了MAD-Bench,一个包含8…

网站打不开怎么办,收藏以备不时之需

DNS设置示范教程 部分地区有使用移动网络的小伙伴们吐槽无法访问部分网站的情况,同样的网站,使用电信和联通的用户就能正常访问。 这其实有很大几率是由于运营商的网络问题导致的,容易出现网站打不开的结果。 要解决移动网络无法访问的情况…

(面试必看!)一些和多线程相关的面试考点

文章导读 引言考点1. CAS 指令(重点)一、什么是CAS二、CAS 的优点三、CAS 的缺点四、ABA问题五、相关面试题 考点2. 信号量(semaphore)一、基本概念二、信号量的主要操作三、信号量的应用四、相关面试题 考点3、CountDownLatch 类…

DHCP笔记

DHCP---动态主机配置协议 作用:为终端动态提供IP地址,子网掩码,网关,DNS网址等信息 具体流程 报文抓包 在DHCP服务器分配iP地址之间会进行广播发送arp报文,接收IP地址的设备也会发送,防止其他设备已经使用…

卓码软件测评:软件功能测试和非功能测试详情介绍

随着信息技术的不断发展,软件在我们日常生活与工作中扮演着越来越重要的角色。然而,软件质量的好坏直接关系到使用者的体验和企业的声誉。在软件开发过程中,功能测试和非功能测试作为保证软件质量的重要手段,受到了越来越多的关注…