本文仅供技术学习使用,欢迎转载,转载请注明出处

因为朋友参加数学建模,需要景点数据,而我刚好懂一点点,就帮他写爬虫代码。在网上搜索到一些爬虫方法,但在获取景点ID时,发现现在携程的Request Payload参数发生变化,导致原本的一些参数,如翻页的请求Fetch,景点ID:viewid没有了,经过分析发现使用了poiID作为新的参数,故自己重新针对新的接口参数重新写了爬虫,同时对爬取通过ajax实现的翻页的数据进行总结,如有错误,还望包涵并指出!

PS:携程原本的接口参数还是能正常使用,也可以正常爬取。就是查不到那些借口参数
如果有人知道原因,或者找到viewid的方法,还望不吝赐教

爬取携程景点评论数据

  • 分析过程
    • 页数跳转两种方式
    • 分析评论数据请求接口
    • 分析评论返回数据
  • 源码拆解
    • 将需要爬取的景点信息写入数组
    • 根据数组,修改请求参数,进行第一次请求
    • 确定评论总页数
    • 创建写入csv文件
    • 通过循环遍历页数,爬取评论数据并保存
  • 源码分享

分析过程

前言提到,携程的Request Payload参数发送了变化,需要重新分析接口参数和返回结果。

这里简单提一下为什么需要通过接口获取评论数据:

页数跳转两种方式

因为评论数过多,所有网页大多采用分页的形式展示,用户可以通过点击相应的页数跳转

而跳转页数目前有两种实现方式:

第一种是通过网址参数,如豆瓣网。常见的爬取豆瓣电影top250就是这种方式。

我们进入https://movie.douban.com/top250,查看页面数据。

第一页:

第二页:

可以看到,这个网页是通过网址参数"start="的变化,跳转到不同的页面。

这样在爬取数据时,只需要变化网址参数就可以获取不同页数的数据,获取难度相对简单。

而第二种就是携程这样,通过ajax技术,动态加载评论数据

第一页:

第二页:

可以看到网址未发生变化,但数据已经加载进来。

对于这种方法,我们需要去查看它的调用接口,并使用固定参数去获取返回数据,获取难度相对增大。

言归正传,本文不对以上两种方式做赘述,只针对携程景点评论数据进行分析

分析评论数据请求接口

我们在携程景点评论页面按’F12’进入元素检测,点击’Network’查看网络资源。因为我们需要的是评论页数变化时的请求数据,为了防止其他数据干扰,我们先清空所有数据,再点击第二页,加载数据,可以看到此时所有网络请求资源被嗅探到。等数据不再变化时,停止监听,此时看到的就是请求评论第二页的所有数据。

从图上可以看到,这些数据里一部分是图片资源,因为我们需要的是用户评论数据,所以不用管。另外两个文件是评论请求数据,从文件名:getCommentCollapseList 也可以判断处理。

再看文件类型Type,一个是preflight request(预检请求),这个是为了确保数据安全,详细的可以了解这篇文章(侵删)

另一个就是我们的主角,Fetch API。我们点击这个文件,可以查看Hearders里的内容

在这些里面,我们需要关注的是Request URL:和Request Payload

Request URL:https://m.ctrip.com/restapi/soa2/13444/json/getCommentCollapseList

可以推测这个是请求的地址,而且是通用接口网址,评论信息都是通过这个网址获取的

Request Payload,这是一种请求方式,我们只需要关注它的具体参数,把它拿出来

"arg":{"channelType":2,"collapseType":0,"commentTagId":0,"pageIndex":2,"pageSize":10,"poiId":97470,"sourceType":1,"sortType":3,"starType":0},"head":{"cid":"09031027214030973865","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","xsid":"","extension":[]}

我们可以看到这是个JSON格式,但我们不清楚每个参数的具体含义,这时候先别急,有一个简单的方法,那就是先打开一个新的景点,用同样的方法获取这些参数,通过简单的对比法,确定变化的参数。而这个参数,很有可能就是不同景点的区别。

我们重新打开”宋城“的网页,如法炮制,查看请求参数。

可以看到Request URL不变,进而印证我们之前的猜测。

再拿出Request Payload

 "arg":{"channelType":2,"collapseType":0,"commentTagId":0,"pageIndex":2,"pageSize":10,"poiId":10558619,"sourceType":1,"sortType":3,"starType":0},"head":{"cid":"09031027214030973865","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","xsid":"","extension":[]}

可以看到,除了poiID这个参数,其他都没有变化,进而确定

所有评论信息都是通过一个相同的地址获取的,而poiID 就是区分不同景点的景点ID

至此,ajax的请求接口分析完成

PS:"arg"里还有一个参数:pageIndex,望文生义,我们也能确定它就是页数的下标,点击不同页数,它也会相应发生变化,这个参数,我们后面写代码会使用到。

分析评论返回数据

还是刚才的Fetch参数页面,这次我们点击Preview,这里是请求成功后,返回的数据,我们可以在这里查看返回的具体数据,方便后面写代码时直接获取相应的值。

它返回的也是JSON格式的数据,我们可以看到,在result 下 的 items里有10个列表,我们点开其中一个

正主终于出现了,content里面的就是评论信息。我们也由此确定返回值的路径:result->items->[n]->content

但拿到这个路径,我们就可以开始写代码了吗?

还不行。因为我们还有一个关键的值没找到,那就是一共有多少条评论信息。

我们只有知道这个,才好动手开始写代码。我们可以推测,这个信息肯定会包含在获取到的这个数据里,不然页面上怎么显示有多少条,确定有多少页?

我们继续看,可以发现一个参数:totalCount:总数量

为了验证,我们再返回到页面上,

丝毫不差,现在终于可以开始写代码了

源码拆解

将需要爬取的景点信息写入数组

postUrl="https://m.ctrip.com/restapi/soa2/13444/json/getCommentCollapseList"# 将景点poiId和名称添加到此处
urls = [['97470','千岛湖']]

我们定义一个变量,来储存需要爬取的网址。

再创建一个数组,加入需要爬取的景点ID及名称

根据数组,修改请求参数,进行第一次请求

for id in urls:print("正在爬取景点:", id[1])data_pre={"arg":{"channelType":2,"collapseType":0,"commentTagId":0,"pageIndex":1,"pageSize":10,"poiId":id[0],"sourceType":1,"sortType":3,"starType":0},"head":{"cid":"09031027214030973865","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","xsid":"","extension":[]}}html=requests.post(postUrl,data=json.dumps(data_pre)).texthtml=json.loads(html)

根据上述分析,在请求接口时需要相应参数,我们将之前获取的Request Payload参数拿出来,做成JSON文件,并将里面的“poiID”(景点ID)的值换成从景点数组中获取的变量,然后通过requests模块中的post函数,加入请求地址和参数,进行一次请求。并将获取到的数据通过JSON格式加载。

确定评论总页数

 # 确定总页数总页数total_page = int(html['result']['totalCount']) / 9if total_page > 200:total_page = 200# 遍历查询评论print("总页数:", total_page, "爬取中")

根据分析得到的"totalCount"路径,我们把总评论数的值取出来,因为在分析获取数据时,发现每一页只有十条数据,并且根据页数的变化,请求参数中的"pageIndex"参数也会发生变化,所以通过简单计算算出总页数,并保证页数不超过200页,即2000条数据。(需求上要求的)

创建写入csv文件

 # 创建写入csv文件path = str(id[1]) + '.csv'xuhao = 0with open(path, 'w', newline='', encoding='utf-8') as f:file = csv.writer(f)file.writerow(['序号', '景区ID', '景区名称', '评论'])

将景点名称作为文件名,为每个景点创建一个csv文件保存评论数据,使用utf-8编码

通过循环遍历页数,爬取评论数据并保存

for page in range(1, total_page+1):data={"arg":{"channelType":2,"collapseType":0,"commentTagId":0,"pageIndex":page,"pageSize":10,"poiId":id[0],"sourceType":1,"sortType":3,"starType":0},"head":{"cid":"09031027214030973865","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","xsid":"","extension":[]}}html=requests.post(postUrl,data=json.dumps(data)).texthtml=json.loads(html)# 获取评论for j in range(0,9):result = html['result']['items'][j]['content']file.writerow([xuhao, id[0], id[1], result])xuhao += 1

将参数中"pageIndex"的值换成变量,从计算出的总页数进行遍历,根据分析得出的评论路径,获取到具体评论并写入scv文件中。

到此,代码编写完成。下面贴出源码,方便查看。

源码分享

import requests
import json
import csvpostUrl="https://m.ctrip.com/restapi/soa2/13444/json/getCommentCollapseList"# 将景点poiId和名称添加到此处
urls = [['97470','千岛湖']]for id in urls:print("正在爬取景点:", id[1])# 通过返回值判断总评论数,每页9条,计算出总页数,对大于2000条的数据只爬取两千条data_pre={"arg":{"channelType":2,"collapseType":0,"commentTagId":0,"pageIndex":1,"pageSize":10,"poiId":id[0],"sourceType":1,"sortType":3,"starType":0},"head":{"cid":"09031027214030973865","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","xsid":"","extension":[]}}html=requests.post(postUrl,data=json.dumps(data_pre)).texthtml=json.loads(html)# 确定总页数总页数total_page = int(html['result']['totalCount']) / 9if total_page > 222:total_page = 222# 遍历查询评论print("总页数:", total_page, "爬取中")# 创建写入csv文件path = str(id[1]) + '.csv'xuhao = 0with open(path, 'w', newline='', encoding='utf-8') as f:file = csv.writer(f)file.writerow(['序号', '景区ID', '景区名称', '评论'])for page in range(1, total_page+1):data={"arg":{"channelType":2,"collapseType":0,"commentTagId":0,"pageIndex":page,"pageSize":10,"poiId":id[0],"sourceType":1,"sortType":3,"starType":0},"head":{"cid":"09031027214030973865","ctok":"","cver":"1.0","lang":"01","sid":"8888","syscode":"09","auth":"","xsid":"","extension":[]}}html=requests.post(postUrl,data=json.dumps(data)).texthtml=json.loads(html)# 获取评论for j in range(1,10):result = html['result']['items'][j]['content']file.writerow([xuhao, id[0], id[1], result])xuhao += 1print(id[1], "爬取完成")

爬取携程景点评论数据【最新方法】,分析AJAX实现页数跳转的爬取方法相关推荐

  1. python爬携程景区评论_python爬取携程景点评论信息

    python爬取携程景点评论信息 今天要分析的网站是携程网,获取景点的用户评论,评论信息通过json返回API,页面是这个样子的 按下F12之后,F5刷新一下 具体需要URL Request的方式为P ...

  2. pyhton爬虫(12)——抓取携程酒店评论数据

    本文主要目标是抓取携程酒店基本信息和用户评论数据.具体来说,酒店基本信息包括:酒店名.酒店星级.酒店最低房价.用户推荐比.酒店总评分等:用户评论数据包括:用户评论时间,用户评分,评论内容等. 实现代码 ...

  3. 用python爬网站评论_python爬取携程景点评论信息

    今天要分析的网站是携程网,获取景点的用户评论,评论信息通过json返回API,页面是这个样子的 按下F12之后,F5刷新一下 具体需要URL Request的方式为POST,还需要你提取的哪一页,下面 ...

  4. python爬取携程景点_python爬取携程景点评论信息

    今天要分析的网站是携程网,获取景点的用户评论,评论信息通过json返回API,页面是这个样子的 按下F12之后,F5刷新一下 具体需要URL Request的方式为POST,还需要你提取的哪一页,下面 ...

  5. python携程酒店评论_python爬取携程景点评论信息

    今天要分析的网站是携程网,获取景点的用户评论,评论信息通过json返回API,页面是这个样子的 按下F12之后,F5刷新一下 具体需要URL Request的方式为POST,还需要你提取的哪一页,下面 ...

  6. 爬取携程中评论的数据

    爬取携程中评论的数据 1.爬取评论的发布者 2.爬取评论发布的时间 3.爬取评论的内容 在爬取这个携程数据时,将使用selenium自动化的去获取网页数据将网页数据下载下来,使用的是chrom驱动程序 ...

  7. python爬携程上出境游数据_python爬取携程旅游评价信息词云图分析

    python爬取携程旅游评价信息词云图分析 前言 前面咱们已经分析过如何爬取携程旅游的相关信息,如果没有看过的,可以先跳转看一下前面的那篇博客:python 爬虫 一键爬取携程旅游团数据 这一篇呢,咱 ...

  8. python爬取携程旅游评价信息词云图分析

    python爬取携程旅游评价信息词云图分析 前言 前面咱们已经分析过如何爬取携程旅游的相关信息,如果没有看过的,可以先跳转看一下前面的那篇博客:python 爬虫 一键爬取携程旅游团数据 这一篇呢,咱 ...

  9. 爬取携程景点可能遇到的问题

    打开文件要加上encoding否则可能GBK编码错误 携程的某些数据无法爬取,获得的HTML里不是真实数据 获取li列表个数有变化的时候最好用selector,获得整个列表,然后再分离 strip() ...

最新文章

  1. 目标检测--A Unified Multi-scale Deep Convolutional Neural Network for Fast Object Detection
  2. 之一:CABasicAnimation - 基本动画
  3. Android 图文混排 通过webview实现并实现点击图片
  4. 【渝粤题库】陕西师范大学151205 财务管理原理作业(笔试题型)
  5. Elasticsearchan相关插件和工具安装
  6. 刚一下雪,中国就美哭了全世界!
  7. node.js——麻将算法(三)胡牌相关明牌
  8. 容器化Go应用--基础镜像的未知时区问题
  9. python注册登陆程序未响应_SpringBoot实现登录注册常见问题解决方案
  10. PCIE知识点-002:PCIE协议中的几种bridge
  11. Multisim高频电子线路4.7振荡器仿真
  12. java 读取文件成字节数组_java读取文件为字节数组
  13. 风力摆控制系统,stm32f1程序,通过pid控制算法实现了风力摆摆定长直线,变长直线,一定角度摆动,定点停滞
  14. wifi信号强度测试软件 mac,Wifi Signal Strength for Mac(无线WiFi信号强度统计软件)
  15. 什么是xapk文件?
  16. JSON.stringify(value, replacer, space)详解
  17. DVD转VCD,MPG文件参考
  18. 浅谈:机房监控联网报警系统!
  19. win10删除.x文件的在“你要如何打开这个文件”的某个无效应用
  20. linux redis 日志在哪里,Redis的日志系统

热门文章

  1. 正交的概念以及正交实验
  2. 隐藏链接地址进行页面的跳转
  3. java 某会员本月购物5次_Java基础循环练习题
  4. 企业财务报表的分析方法(The analysis of financial statements)
  5. 《数据分析师养成宝典》
  6. WebSocket简单调用
  7. 破解者是如何篡改游戏内数值的,揭秘Android手游破解全过程
  8. java中文分词算法
  9. html+js实现点赞
  10. 联想 G510 AMD 显卡安装卡死