【Python3 爬虫、数据清洗与可视化实战】大型爬虫案例:抓取某电商网站的商品数据

观察页面特征和解析数据

实现一个大型爬虫,抓取某旅游电商网站中某个频道的所有商品数据。

实现爬虫的第一步是观察页面特征和解析数据。通过对比PC端和无线端,这里决定数据采集自无线端,原因是无线端返回的数据是JSON格式的。JSON格式的数据比较容易处理,所以在获取数据的时候最好选择JSON格式的数据。

这里以某旅游电商网站:https://www.qunar.com/为例
通过浏览器访问该旅游电商官网,如下图所示:
在这里插入图片描述
接下来按【F12】键进入开发者模式,单击“自由行”选项进入自由行频道,如下图所示:

在这里插入图片描述
在这里插入图片描述
在自由行频道中点击搜索框,如下图所示:

在这里插入图片描述
在Network下,点击JS,选取一js文件单击,在文件的Preview(预览)界面可以观察到树状结构,如下图:

在这里插入图片描述
切换到Headers(请求头)页面,在General(总体)信息中有以下两条重要信息:
(1)Request URL(请求链接):将通过这个链接访问服务器获取数据。
(2)Request Method(请求方式):决定使用的函数方法和上传参数。常见的请求方式有GET方式和POST方式,其中GET方式权限单一,只有查询数据的权限,只要访问URL就可以返回数据;POST方式需要权限验证和请求内容,服务器通过权限放行,通过请求内容返回客户端请求的数据,POST方式具有查询和修改数据的权限。

如下图所示,请求方式为GET方式

在这里插入图片描述
在获取数据的时候,需要将Request URL(请求链接)的最后一个callback参数删掉,即目标URL如下:

https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep=%E5%8C%97%E4%BA%AC&exclude=&extensionImg=255,175

单击推荐列表中的任意一个城市,通过观察可以发现数据在XHR(用XMLHttpRequest方法来获取JavaScript)中

在这里插入图片描述
切换到Headers页面,观察Request URL(请求链接)和Request Method(请求方式),如图所示:

在这里插入图片描述
其中Request URL(请求链接)如下:

https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep=%E5%8C%97%E4%BA%AC&query=%E5%8E%A6%E9%97%A8%E8%87%AA%E7%94%B1%E8%A1%8C&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=%E5%8E%A6%E9%97%A8%E8%87%AA%E7%94%B1%E8%A1%8C&width=480&height=320&quality=90&limit=0,24&includeAD=true&qsact=search&filterTagPlatform=mobile_touch

这个地址中以%开头的字符串是中文编译成的字符串,由于服务器不能识别中文字符,所以必须将中文以某种编码方式进行编译后才能提交到服务器。在此笔者使用在线编码转换进行解码

在这里插入图片描述

通过该工具还原后的URL如下:

https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep=北京&query=厦门自由行&dappDealTrace=true&mobFunction=扩展自由行&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery=厦门自由行&width=480&height=320&quality=90&limit=0,24&includeAD=true&qsact=search&filterTagPlatform=mobile_touch

经过解码还原后,可以观察到这里使用的是utf-8编码,其中dep参数表示出发地(北京),query和originalquery表示目的地(厦门),通过修改这两个参数就可以控制遍历整个平台的自由行产品。

由于目标是获取整个自由行的产品列表,因此还需要获取出发地站点的列表,从不同的城市出发,会有不同的产品。

如下图,单击“北京出发”,如下图所示:

在这里插入图片描述
可以看到,全国各地出发地站点按字母排序,在右侧的开发者页面中可以找到对应的数据包,如下图所示:

在这里插入图片描述
在这里插入图片描述
然后切换到Headers页面,观察Request URL(请求链接)和Request Method(请求方式),如下图所示:
在这里插入图片描述
此时的目标URL如下:

https://touch.dujia.qunar.com/depCities.qunar

工作流程分析

完成上述的解析后,接下来实施这个爬虫,步骤如下:
(1)获取出发站点列表
(2)获取旅游景点列表
(3)获取景点产品列表
(4)存储数据

构建类目树

首先获取出发站点列表,输入以下代码:

import requests
url = 'https://touch.dujia.qunar.com/depCities.qunar'   # 出发站点列表链接
strhtml = requests.get(url)     # GET方式,获取网页数据
dep_dict = strhtml.json()       # requests库返回的数据编码成JSON格式的数据
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        print(dep)


代码运行结果为:

在这里插入图片描述
然后根据出发地站点列表获取旅游景点列表(目的地列表),继续输入以下代码:

import requests
import urllib
import time
url = 'https://touch.dujia.qunar.com/depCities.qunar'   # 出发站点列表链接
strhtml = requests.get(url)     # GET方式,获取网页数据
dep_dict = strhtml.json()       # requests库返回的数据编码成JSON格式的数据
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        print(dep)
        #新加入的代码
        url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(dep)
        time.sleep(1)
        strhtml = requests.get(url)
        arrive_dict = strhtml.json()
        for arr_item in arrive_dict['data']:
            for arr_item_1 in arr_item['subModules']:
                for query in arr_item_1['items']:
                    print(query['query'])

运行结果如下:

在这里插入图片描述

通过观察打印结果发现,目的地列表有多个重复项(在网页上也可以发现),如果基于这个有重复项的类目树获取数据,就会造成资源浪费,因此要先对目的地列表进行去重。接下来,在上段代码中补充去重的代码:

import requests
import urllib
import time
url = 'https://touch.dujia.qunar.com/depCities.qunar' #出发点列表的链接
strhtml = requests.get(url)
dep_dict = strhtml.json()
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        a=[]        #新加入的代码
        print(dep)
        url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(dep)
        time.sleep(1)
        strhtml = requests.get(url)
        arrive_dict = strhtml.json()
        for arr_item in arrive_dict['data']:
            for arr_item_1 in arr_item['subModules']:
                for query in arr_item_1['items']:
                    if query["query"] not in a:
                        a.append(query["query"])
        print(a)

运行结果如下:
在这里插入图片描述
由于去重针对的是每个出发地站点下的目的地,因此需要在获取出发站点的位置定义一个空的列表a,每次循环都会重置a。
最后判断目的地是否在列表a中,如果没有,就用appand()(合并)方法将目的地加入列表a中,代码如下:

if query["query"] not in a:
	a.append(query["query"])

获取景点产品列表

完成出发点站点列表和目的地列表的构建后,输入以下代码以便获取景点产品列表:

import requests
import urllib
import time
import pymongo
client = pymongo.MongoClient('localhost',27017) #建立连接
book_qunar = client['qunar'] #建立名为“zijiqi” 的数据库
sheet_qunar = book_qunar['sheet_qunar'] #在数据库中创建新表 “sheet_zijiqi”
url = 'https://touch.dujia.qunar.com/depCities.qunar' #出发点列表的链接
strhtml = requests.get(url)
dep_dict = strhtml.json()
for dep_item in dep_dict['data']:
    for dep in dep_dict['data'][dep_item]:
        a=[]
        url = 'https://touch.dujia.qunar.com/golfz/sight/arriveRecommend?dep={}&exclude=&extensionImg=255,175'.format(dep)
        time.sleep(1)
        strhtml = requests.get(url)
        arrive_dict = strhtml.json()
        for arr_item in arrive_dict['data']:
            for arr_item_1 in arr_item['subModules']:
                for query in arr_item_1['items']:
                    if query['query'] not in a: #使得当前出发点对应的目的地不重复
                        a.append(query['query'])

        for item in a:
            url = 'https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep={}&query={}&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery={}&width=480&height=320&quality=90&limit=0,24&includeAD=true&qsact=search&filterTagPlatform=mobile_touch'.format(urllib.parse.quote(dep),urllib.parse.quote(item),urllib.parse.quote(item))

            time.sleep(1)
            strhtml = requests.get(url)
            routeCount = int(strhtml.json()['data']['limit']['routeCount']) #取出产品数
            for limit in range(0,routeCount,20): #获取产品信息
                url = 'https://touch.dujia.qunar.com/list?modules=list%2CbookingInfo%2CactivityDetail&dep={}&query={}&dappDealTrace=true&mobFunction=%E6%89%A9%E5%B1%95%E8%87%AA%E7%94%B1%E8%A1%8C&cfrom=zyx&it=dujia_hy_destination&date=&needNoResult=true&originalquery={}&width=480&height=320&quality=90&limit={},24&includeAD=true&qsact=search&filterTagPlatform=mobile_touch'.format(urllib.parse.quote(dep),urllib.parse.quote(item),urllib.parse.quote(item),limit)
                time.sleep(1)
                strhtml = requests.get(url)
                #产品的数据类型
                result = {
                    'date': time.strftime('%Y-%m-%d',time.localtime(time.time())),
                    'dep': dep,
                    'arrive': item,
                    'limit': limit,
                    'result': strhtml.json()
                }
                sheet_qunar.insert_one(result)

  • 2
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
教案标题:Python爬虫数据分析与可视化 教案简介: 本教案旨在教授Python爬虫数据分析和可视化的基本概念和技术。通过学习本教案,学生将能够掌握如何使用Python编写爬虫程序,获取并分析网络数据,然后利用可视化工具将分析结果以图表形式展示出来。通过这一过程,学生不仅能够掌握Python编程的基础知识,还能够了解如何在现实生活中应用这些技术进行数据分析和可视化。 教案内容: 1. Python爬虫基础 - 网络爬虫的概念及其应用领域 - 使用Python的第三方库BeautifulSoup和requests进行网页解析和访问 - 网络数据抓取和存储的基本方法 2. 数据分析基础 - 数据分析的概念和基本过程 - 使用Python的pandas库进行数据处理和分析 - 数据清洗、转换和整合的方法 3. 数据可视化 - 数据可视化的重要性和应用领域 - 使用Python的matplotlib和seaborn库进行数据可视化 - 不同类型的图表和图形的绘制方法 4. 实际应用案例 - 实际数据分析和可视化案例的讲解和分析 - 学生参与实际项目的设计和实施 教学目标: 通过本教案的学习,学生将能够: 1. 理解Python爬虫的基本原理和应用方法; 2. 掌握数据分析的基本概念和技术,包括数据清洗、转换和整合; 3. 学会使用Python的matplotlib和seaborn库进行数据可视化; 4. 运用所学知识解决实际问题,进行数据分析和可视化。 教学方法: 本教案采用理论与实践相结合的教学方法,其中理论部分通过讲解和示范进行,实践部分通过实际项目和案例分析进行。教师将充当指导者和引导者的角色,鼓励学生主动参与讨论和解决问题。 学生评估: 学生的学习成绩将通过学习笔记、实际项目和期末考试进行评估。学生需要完成一个小组项目,包括数据爬取、清洗、分析和可视化,并撰写项目报告。 教学资源: 为了完成本教案的学习,学生需要准备以下资源: - 一台配置良好的电脑; - 安装Python编程环境,包括Python解释器和相应的第三方库; - 下载和安装相应的开发工具和开发环境; - 互联网连接和浏览器。 通过本教案的学习,学生将获得基本的Python爬虫数据分析和可视化的技能,为日后的数据科学和程序开发奠定良好的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你是誰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值