Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >聊聊爬取某团数据

聊聊爬取某团数据

作者头像
我被狗咬了
发布于 2022-01-05 00:44:21
发布于 2022-01-05 00:44:21
89900
代码可运行
举报
文章被收录于专栏:Python乱炖Python乱炖
运行总次数:0
代码可运行

正所谓:民以食为先,食以安为先,今天我们来爬取某团的美食店家数据,看看有什么好吃的,有哪些优惠套餐。

爬前分析

URL请求参数

首先进入美团并打开开发者工具,如下图所示:

可以发现商店数据保存在上图中的红框3中的URL链接,那么我们看看该URL长什么样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://fs.meituan.com/meishi/api/poi/getPoiList?cityName=%E4%BD%9B%E5%B1%B1&cateId=0&areaId=0&sort=&dinnerCountAttrId=&page=1&userId=1570290508&uuid=6c096f87c97a427abf04.1640047401.1.0.0&platform=1&partner=126&originUrl=https%3A%2F%2Ffs.meituan.com%2Fmeishi%2F&riskLevel=1&optimusCode=10&_token=eJx1T01vqkAU%2FS%2BzLXFmhBnApAu0ArZIpT5KselCEZkRhcKMqDT9750mvsVbvOQm5%2BOenNz7BdrZFowwQjZCGujyFowAHqABBRqQQm2ogRDBBBGCDA1k%2F3qWZWpg074%2BgNG7QUyNEvPj13hR%2Bh3rlGomtT60Gx0qOjTU%2FGZmKgKYlJ9iBOFODI45l6d1NcjqI1RcMA7VCf8JANVw%2FKMaFJY3XN9Q%2FtVz9YqqELyoFMsfz4d9jJtz70Qsv1uy1eZ6nbDkLXT4yo1rfRc7U%2F2UcbdZeil6WsRyUUYLFIrSrmXweqdzq7qgq5F3IopRbTv2uJPWpWwhhPvLKewT%2FzBji9MyJbx6CJrg8siDJLPKPi%2FmdRZw17aem252kIRumgOdsvETT22yLXAgd1EToa7dTqafMabobDcJ9pI%2B8Ff%2BvK08XX8Ztqx0G7upNxYU%2Bi7amxO%2FoDXufZqm42tSEOkxc6Xnrums92HqPAvheQitw8J23mC83Mb34PsHk8iWQw%3D%3D

其中token参数值是我们常人不能看懂的,点击网页的下一页,可以发现,新的URL请求参数只有page、originUrl、token这三个请求参数发生变化,其中page参数、orginUrl参数是控制翻页而且有规律的,token参数是没规律的,所以我们只要破解token加密参数的加密方式就可以获取到该URL链接的所有数据了,由于token参数最后一个字符是以等号结尾,那么有极大可能是通过base64加密的。

代码测试

那么我们来简单地写个爬虫测试,来测试使用这些参数能不能获取数据,主要代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
url='https://fs.meituan.com/meishi/api/poi/getPoiList?'
params = {
    'cityName': '佛山',
    'cateId': '0',
    'areaId': '0',
    'sort': '',
    'dinnerCountAttrId': '',
    'page': '2',
    'userId': '自身的ip',
    'uuid': '47e30751bdcc4cb3b9ca.1639966171.1.0.0',
    'platform': '1',
    'partner': '126',
    'originUrl': ' https://gz.meituan.com/meishi/pn2/',
    'riskLevel': '1',
    'optimusCode': '10',
    '_token': 'eJyFT8luo0AQ/Ze+BrlplgYszcEYxBYWAzZ2ohwwBpsQmh07jubf05Gcw5xGKukt9fRU9QV66wSWiGUVlmXAnPdgCdCCXWDAgHGgGyywrMgjJIsCYkD2ryfL1Dv2Ow0sXwVRYrAovf0YIdWviMeYkbD8xjwoRykn0PnJWDQCLuPYDksIi2FR5+U4pWSRNTWkfLiUsCUcpGf8L4QgoIV1TAspVg9MHzj+apd+RtuG8kwoy+3rxz1D3uqub9RczbNZC82P2febudqIm1ifbGOVBdPRcG6w1ZWws5KuOqunlacc3LgtDjlRruJhHSp7jbPVlsg6JO9GFEgShgEpLqc+skhnF4X+8nTAfmnttd7gIyTZ6W0tXurReub3vPd0jMw2Tuvmup0MP4oEsZs8bu0MVbMtVIdvPpvASBWvdRsfOkkKwxR5Wk6m8qRMRuLwc2hApODO1VzZDePumR+Ctj3vSRrX+MXc9e+yudUcuKtW6ee9cZLE8s3rWnKd6Lb9A/5+A0x9m9s=',
}
#发送网络请求
response=requests.get(url,headers=headers,params=params).json()
print(response)

运行结果如下所示:

我们通过URL的参数可以获取到数据,但过几分钟后再用上面的代码来获取数据就会报错,如下图所示:

可以推测这token加密最重要的参数与时间有关。

token加密

打开开发者工具,点击右上角三个小点,选择Search,搜索token,如下图所示:

搜索结果如下图所示:

可以发现,只有一个js文件,双击打开该js文件,并搜索token,如下图所示:

从图中可以发现,token参数值是d这个变量,而d由window.Rohr_Opt.reload()方法获得,在该方法中要传递p参数,问题来了p参数是什么呢,我们在2528行代码设置断点,并刷新页面,如下图所示:

是不是觉得p参数的值很熟悉,该参数正是我们要访问的URL链接而且没有token值。那么我们进入window.Rohr_Opt.reload()方法中,看看该方法是怎样的,如下图所示:

该方法大概意思是创建jw,jx变量,把jv值进行切割处理,将处理好的jv赋值给jx并传递到iJ()方法中,再把iJ()方法的返回值赋给iP.sign。我们在上一步中的代码测试中推测token加密与时间有关,果然不出所料,该方法确实需要传递时间参数。通过new Date().getTime()方法获取到的时间传递到iP.cts中,再把iP参数传递到iI()方法中并把返回值返回给jw,最后通过encodeURIComponent()进行编码,并结果返回。

那么我们在3369行代码中设置断点,并刷新页面,如下图所示:

可以发现该jv正是我们上面所说的p参数,经过系列的切割,最终得到的jx,那么我们进入iJ()方法并观察该方法的作用,如下图所示:

在iJ()方法中并没有看到有关随机数之类的参数、方法,并且经过一系列的寻找,也没有发现有有关随机数、时间的参数和方法,只要在网页中下图中的选项不变,那么iJ()返回出来的是定值。:

如下图所示,jx参数值除了page、originUrl这两个参数可能会发生变化,其他的都是定值:

在代码测试中,同一个token参数值,前几分钟可以请求成功,但过几分钟都就请求失败,那么可以推测时间是最重要的参数,而page、originUrl参数可以看作是定值。其中iP.cts负责存放系统时间,

我们进入浏览器的控制台console,并在控制台输入iP,如下图所示:

我们发现里面有一个名为cts参数,而在上面的iP.cts中接收一个系统时间。

要么一开始iP中的cts参数值为空,当代码运行到3364行的时候,再将系统时间传进去;要么是一开始有个时间,当代码运行到3364行的时候,再将cts参数值进行替换当前系统时间。不管怎样,cts参数都是当前系统的时间。

在控制台iP中,还有一个参数ts,而且比cts参数值小,在代码测试中,同一段代码,一开始可以运行并获取数据,而过几分钟后就运行会报错,这就说明了ts与cts影响着token参数,经过我们的测试,修不修改这个ts参数对token没影响,

将iP中的cts参数值替换后,再将iP传入iI()方法进行处理加密,最后返回jw。

进入iI()方法并观察其作用,如下图所示:

iI()方法大概是通过delate算法来把传入的iP数据进行压缩,压缩后断点代码再使用iD方法进行处理。那么问题来了,这些方法都是一个接着一个来套用,iD方法肯定又套用了其他方法,这样我们很难通过构造js方法来破解token加密。

怎么办好呢,首先token参数最后一个字符是以等号结尾,那么有极大可能是通过base64加密的,而且token参数加密最重要的是cts时间参数,那么我们投机取巧,只需要将在源代码Sources中复制jw参数下来,通过base64解码并将cts时间参数值替换成当前系统时间,再通过base64加密就可以获取到token参数值了。

好了,token参数加密已经成功通过我们的投机取巧破解出来了,接下来我们正式爬取某团商店的数据了。

实战演练

token参数获取

我们来复制jw参数并通过解码、替换、编码等一些列操作来获取token参数值,主要代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    jw= "eJx1T11Po0AU/S/zCikzAwzQxIeCWqELlkpbWeMDRRgoA7QMUNH433dMui8mJjc5H/fk5N5P0LlvYI4gtCCUwZh1YA7QDM4IkEHPxYZoEGsGJgRCIoP0h6cL79DtbsH8BauGTHTj9dvYCP2CVEJkg5iv8pViQbEm5jvjiggo+v7E54pCP2Z1VvZD0szStlYE50WpiBN+CQDRUEeiQWB1xeSK/X/ti1dEBS9pI1jmXdgxQsNiuguLTCnpyb23H+hbmXrT/RNbsYtPfUTWnNvnpXPRC7NCLQv1Y2ZuWhaN0FobeLt3JG9y7obcNReKa1lZ7EaTlL/reTN5xWrrNJjyvN6zahPAOMVSU5d26z11BR32AWpspvZdFDgw92kwHeE+S3Rt2U/9Y9yOf1aLS/FwCuzlJOEgX7FtoeH4uVfoZuAUcXZ7dlVpPUaHs+KHUYVKS3u3M/PxUFuLRJdSK2xqvJsqi8V/E13dbSvOUKY9F6PnNeHNDfj6By7+lng="
    # 将jw进行解码
    jw= base64.b64decode(jw)
    # 解码后的参数进行解压转换为字符串
    jw = str(zlib.decompress(jw), 'utf-8')

首先我们在源代码Sources中复制jw参数值,通过base64.b64decode()方法将jw参数进行解码,然后在通过zlib.decompress()方法对解密后的jw参数进行解压并用str()方法将解压后的字节转换为字符串。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 将字符串转换为表达式
jw = eval(jw)
# 将jw中的cts参数替换
jw['cts'] = int(time.time() * 1000)
# 编码字符串
jw = str(jw).encode()
# 将jw进行base64编码
token = base64.b64encode(zlib.compress(jw)).decode()

再通过eval()方法将字符串jw当成有效的表达式来求值并返回计算,通过time.time()方法获取当前系统时间并将jw中的cts参数的时间替换,再将替换后的jw转换为字符串并使用encode()方法进行编码,最后使用base64.b64encode进行编码形成我们要的token参数。

数据获取

首先我们发送网络请求,主要代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def get_data():
    #获取token参数值
    token=get_token()
    params = {
        'cityName': '广州',
        'cateId': '0',
        'areaId': '0',
        'sort': '',
        'dinnerCountAttrId': '',
        'page': '1',
        'userId': '自身的id',
        'uuid': '47e30751bdcc4cb3b9ca.1639966171.1.0.0',
        'platform': '1',
        'partner': '126',
        'originUrl': ' https://gz.meituan.com/meishi/',
        'riskLevel': '1',
        'optimusCode': '10',
        '_token': token,
    }
    #发送网络请求
    repsonse=requests.get(url,headers=headers,params=params)
    #将获取的数据传递在自定义方法analysis_data
    analysis_data(repsonse.json())

首先我们自定义字典params来存放请求所需的参数,再通过requests.get()方法来发送网络请求并将请求响应的json数据传递给自定义方法analysis_data()中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def analysis_data(data):
    # 提取解析数据
    data_list=data.get('data').get('poiInfos')
    for i in data_list:
        dealList= i.get('dealList')
        shop = {
            # 商店名
            'shop_name': i.get('title'),
            # 评价数
            'allCommentNum': i.get('allCommentNum'),
            # 评分
            'avgScore': i.get('avgScore'),
            # 平均消费
            'avgPrice': i.get('avgPrice'),
            # 商店地址
            'address': i.get('address'),
            # 优惠套餐
            'dealList': ''
        }
        # 创建优惠套餐数据列表
        food_taocan=[]
        for i in dealList:
            #将数据保存在优惠套餐列表中
            food_taocan.append(i.get('title')+'价格——'+str(i.get('price')))
        #将优惠套餐列表中的数据转换为字符串,并保存在shop字典中的dealList
        shop['dealList']=','.join(food_taocan)
        # 将shop字典中的值以列表的形式传递到自定义方法saving_data中
        saving_data(list(shop.values()))

自定义方法analysis_data接收到数据后,就开始解析数据并将解析到的数据传递给自定义方法saving_data()方法中。

保存数据

在上一步我们成功获取到数据了,接下来我们将获取到的数据保存在MySQL数据库中,主要代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def saving_data(data):
    # 连接数据库
    db = pymysql.connect(host=host, user=user, password=passwd, port=port, db='meituan')
    # 获取游标
    cursor = db.cursor()
    # 插入数据,其中插入的字段分别为商店名,评论数,评分,平均消费,地址,优惠套餐
    sql = 'insert into shopdata(shop_name,allCommentNum, avgScore, avgPrice,address,dealList) values(%s,%s,%s,%s,%s,%s)'
    try:
        # 执行单条sql语句插入数据
        cursor.execute(sql,data)
        print(data)
        # 提交数据
        db.commit()
    except Exception as e:
        # 当保存数据不成功将打印错误信息并取消当前执行的操作
        print(e)
        db.rollback()
    db.close()

首先我们调用pymysql.connect()方法来连接数据库,通过.cursor()获取游标,再通过.execute()方法执行单条的sql语句,执行成功后返回受影响的行数,使用了try-except语句,当保存的数据不成功,就调用rollback()方法,撤消当前事务中所做的所有更改,并释放此连接对象当前使用的任何数据库锁。好了,主要代码已经编写好了,接下来将编写启动爬虫代码,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if __name__ == '__main__':
    for i in range(1,10):
        get_data(i)

结果展示

好了,爬取某团商店数据就讲到这里了,感谢观看!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python乱炖 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python爬取美团网数据这么简单,别再说你不会了哦!
美团网的爬虫整体其实比较简单,通过开发者模式找到真实数据请求地址后,用requests请求的数据格式是标准的json字符串,非常好处理。
可以叫我才哥
2021/08/05
14.4K1
破解美团加密参数_token--------五
大家如果百度过的话,应该关于美团token破解的挺多的,但好多都一样,CSDN都是复制粘贴的,也不是很详细,今天我就说详细一点,当然再说一遍,大神绕过。
andrew_a
2019/07/30
6.3K2
破解美团加密参数_token--------五
聊聊逆向爬取数据
最好的挣钱方式是钱生钱,怎样钱生钱呢,钱生钱可以通过投资,例如买股票、基金等方式,有人可能说买股票基金发财,我没这样的命和运气。买股票基金靠的不只有命运和运气,更多靠的是长期的经验和对股票基金数据的分析,今天我们使用scrapy框架来js逆向爬取某证信数据平台的国内指数成分股行情数据。
我被狗咬了
2021/11/16
1.2K0
聊聊逆向爬取数据
python批量采集美团网餐饮商家评论信息
最近有私信询问可不可以批量采集美团餐饮的商家评论信息,今天晚上刚好有时间就做一个爬虫小教程供大家参考。
你像时光唯美i
2022/08/26
7800
python批量采集美团网餐饮商家评论信息
天一冷,就想大口吃肉,爬取一座城市里的烤肉店数据(附完整Python爬虫代码)
天一冷,就想吃肉,贴好秋膘才能好过冬。对于肉食主义者,吃肉简直幸福感爆棚!特别是烤肉,看着一块块肉慢慢变熟,听着烤盘上“滋滋”的声响,这种期待感是任何其他食物都无法带来的。如果说甜点是“乍见之欢”,那肉则是“久处不厌”。
松鼠爱吃饼干
2022/03/30
3430
天一冷,就想大口吃肉,爬取一座城市里的烤肉店数据(附完整Python爬虫代码)
实战 Python 网络爬虫:美团美食商家信息和用户评论
美食是人类的毕生追求,说到美食,我们总会想起美团美食,面对类型众多的商家,应如何选择优质的商家,使消费最大合理化。在本 Chat 里,将讲述如何爬取美团商家信息。
CSDN技术头条
2018/12/29
4.9K1
实战 Python 网络爬虫:美团美食商家信息和用户评论
某团 + D众点评 美食版块数据分析。
该文章主要提供交流学习使用,请勿利用其进行不当行为! 抽空写个吧,,, 这里讲的是 美团美食和大众点评 至于外卖。 我之前写过文章。。 不再细说。。 某团外卖H5版本X-FOR-WITH参数JS逆向过程 ps:文章已进行更改 - 先从美团开始。 美团美食是一个_token字段。 这个加密,其实满大街都是。。。 百度一下就出来了。 这里就不说加密了。 就是base64 + zip压缩。 这里就说下里面的一些坑。。 如果加密的是纯字符串,,这里要注意一下引号问题, 因为在浏览器中。。 他们
懒py夏洛
2022/06/02
4090
某团 + D众点评 美食版块数据分析。
JavaScript 逆向爬取实战(下)
这一篇是 JavaScript 逆向爬取的第二篇。那么接下来我为大家缕顺一下学习顺序。
崔庆才
2020/05/08
1.3K0
JavaScript加密逻辑分析与Python模拟执行实现数据爬取
本节来说明一下 JavaScript 加密逻辑分析并利用 Python 模拟执行 JavaScript 实现数据爬取的过程。在这里以中国空气质量在线监测分析平台为例来进行分析,主要分析其加密逻辑及破解方法,并利用 PyExecJS 来实现 JavaScript 模拟执行来实现该网站的数据爬取。 疑难杂症 中国空气质量在线监测分析平台是一个收录全国各大城市天气数据的网站,包括温度、湿度、PM 2.5、AQI 等数据,链接为:https://www.aqistudy.cn/html/city_detail.ht
崔庆才
2018/04/04
3K0
JavaScript加密逻辑分析与Python模拟执行实现数据爬取
Python 爬虫进阶必备 | 某众点评 Web 加密参数 _token 逻辑分析
aHR0cHM6Ly93d3cuZGlhbnBpbmcuY29tL3Nob3AvRzNybjh4bEtUR2Q1c0JZeQ==
咸鱼学Python
2021/07/16
6270
用Python爬取网易云音乐的用户评论文本
本文利用Python2.7根据网易云音乐歌曲ID爬取了该歌曲的所有用户评论数据。以id是28875120的歌曲《小岁月太着急》为示例,通过Chrome的DevTools工具获取已加密评论数据,然后基于
机器学习AI算法工程
2018/03/15
1.4K0
用Python爬取网易云音乐的用户评论文本
破解点评网字体反爬,深入挖掘系统背后的原理
从这里可以看到,网页上显示的文字和源码中显示的文字有些出入,并不是一一对应,那继续查看sources中的代码。
州的先生
2019/08/23
9700
破解点评网字体反爬,深入挖掘系统背后的原理
如何获取美团的热门商品和服务
美团是中国最大的生活服务平台之一,提供了各种各样的商品和服务,如美食、酒店、旅游、电影、娱乐等。如果你想了解美团的热门商品和服务,你可以使用爬虫技术来获取它们。本文将介绍如何使用Python和BeautifulSoup库来编写一个简单的爬虫程序,以及如何使用爬虫代理来提高爬虫的效率和稳定性。
jackcode
2023/09/14
4190
如何获取美团的热门商品和服务
十一国庆节旅游美食攻略:Python爬取美团网美食数据,并做可视化展示美食店铺数据
环境介绍: python 3.6 pycharm 安装包 安装教程 使用教程 激活码 插件(翻译插件/汉化插件/主题) Jupyter Notebook 有疑问的同学,或者想要数据集、Python相关资料的可以加群:1039649593 找管理员领取资料和一对一解答 爬虫知识点 动态数据抓包演示 json数据解析 requests模块的使用 保存csv 爬虫代码实现过程 发送请求, 对于找到数据包发送请求 获取数据, 根据服务器给你返回的response数据来的 解析数据, 提取我们想要的内容数据
松鼠爱吃饼干
2021/09/26
9590
批量爬取某音乐网站的音源
通过浏览网页源代码我们可以判断,网页数据是动态加载,还是我们所要获取的数据就在源代码当中,本文中所介绍的XX音乐的音源数据是属于动态加载,我们打开开发者工具,在搜索框中搜索**mp3**,点击**Priview**选项,可以找到我们所要爬取的所有数据,列表页图解如下:
小明要加油
2023/05/09
1.1K0
爬虫入门经典(二十一) | 破解CSS加密之爬取大众点评
在上篇文章中我们已经讲了js加密,这个需要使用者有基本的js阅读和调试能力。但是不一定都解决所有问题,不过可以提供这样的流程和思路。
不温卜火
2020/11/24
2.1K2
爬虫入门经典(二十一) | 破解CSS加密之爬取大众点评
JavaScript 逆向爬取实战
在上一节总结一些网站加密和混淆技术中,我们介绍了网页防护技术,包括接口加密和 JavaScript 压缩、加密和混淆。这就引出了一个问题,如果我们碰到了这样的网站,那该怎么去分析和爬取呢?
崔庆才
2020/05/07
1.9K0
爬虫入门经典(二十二) | 破解base64加密之爬取安居客
前两篇博文我们已经分别讲了js加密与css加密的爬虫,本篇博文我们继续实现base64加密的爬虫。 这里我们以爬安居客为例。那么在讲之前,我们首先需要了解base64加密及其基本原理。
不温卜火
2020/11/24
1.9K0
爬虫入门经典(二十二) | 破解base64加密之爬取安居客
送书 | 用啥selenium!JS逆向不香吗?
正所谓条条道路通罗马,上次我们使用了Selenium自动化工具来爬取网易云的音乐评论,Selenium自动化工具可以驱动浏览器执行特定的动作,获得浏览器当前呈现的页面的源代码,做到可见即可爬,但需要等网页完全加载完,也就是JavaScript完全渲染出来才可以获取到当前的网页源代码,这样的爬取效率太低了、爬取速度太慢了。
我被狗咬了
2021/09/24
1.9K0
Python爬虫爬取网易云音乐全部评论
beautiful now.png 思路整理 访问网易云音乐单曲播放界面,我们可以看到当我们翻页的时候网址是没有变化的,这时候我们大致可以确定评论是通过post形式加载的; .
Awesome_Tang
2018/09/11
1.5K0
Python爬虫爬取网易云音乐全部评论
推荐阅读
相关推荐
Python爬取美团网数据这么简单,别再说你不会了哦!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验