python+爬虫+微信机器人 打造属于你的网购价格监督利器

我们还是使用调试台,其实他页面只要变化,网站交互一定是有活动的,所以我们现在就观察当滚轮往下滚动到瀑布流下端时调试台会出现什么东西就可以了

往下滚动,发现调试台确实出现了很多新的文件,我们猜想这些文件中一定有瀑布流下端的数据,对了还记得我们刚才找到的文件名是什么吗?对的,是名称为graphql开头的文件,那么会不会新的数据文件也是这个名字开头的呢?我们使用调试台搜索下看看

在这里插入图片描述

来了来了,它真的出现了,现在出现了3个文件都是graphql名字开头,毫无疑问第一个文件是我们上面找到的,那么第二个第三个呢? 我们点开看看,会发现对应的商品名称之类的真的是瀑布流下端的数据。

OK看起来我们现在确实得到了所有数据文件的url

我最初的想法是直接将3个url写到一个列表中然后使用循环读取如下图(其实会发现第二个url与第三个看起来貌似一样啊怎么回事?下面有解释别急)

在这里插入图片描述

后来呢我突然意识到,万一商品更多了怎么办?会不会出现4个5个url?而总不能每次都靠人力去数有多少个url吧?然后就想,怎样才能让程序自动添加url呢?

我们再回头看看第一次抓取下来的 url1 的json数据,首先尝试下检索page这个关键词(毕竟一般程序员都会写这个作为页面标识吧?),哦霍,发现了了不得的东西,

在这里插入图片描述

这些数据看起来很眼熟啊,还有uuids?再比对下第一次抓的 url1 发现里面的uuids还真的就是json里面的数据,那么又看到pages里面有个next 纳尼?这会不会是瀑布流下半部分url组成呢?快来比对 url2 地址

https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=%2Fproduct_feed%2Frollup_threads%2Fv2%3Ffilter%3Dmarketplace(CN)%26filter%3Dlanguage(zh-Hans)%26filter%3DemployeePrice(true)%26filter%3DattributeIds(1c7c3d67-5d46-432d-9910-b1128d1b6503%2Ce09eabe9-5ff0-42af-b0a3-5f68af19d89a)%26anchor%3D24%26count%3D24%26consumerChannelId%3Dd9a5bc42-4b9c-4976-858a-f159cf99c647%26sort%3DproductInfo.merchPrice.currentPriceAsc

尝试检索下next中的内容,发现真的存在与endpoint参数后面,哦霍 现在我们猜想,会不会每个json中都包含pages next这个数据

打印url2继续检索pages的next

在这里插入图片描述

真的存在,并且还存在prev参数(前一页),说明我们的猜想可能是正确的,这时候细心的小伙伴可能发现了 url2中的next内容与url1中一致啊,哦原来是这样,这样才导致了我们刚刚调试台中出现3个url文件但是第二个与第三个一样的情况

但是我们猜想第三个url返回数据中应该没有next否则就应该出现第四个文件了,我们来试一试

在url3返回数据中检索next

在这里插入图片描述

真的为空了所以我们可以确定,只要瀑布流下方仍有数据,那么一定存在next参数 因此我们可以确定瀑布流url写法 我们网页分析完成 接下来就要进行真正的代码编写了

(其实我有一个疑问 url2与url3看起来确实是一模一样的并且我尝试做了差值运算,发现还是一样的,但是返回数据确实不同,有大神可以发现这两个url不同之处吗 下面放上这两个url)

(url已改变,根据官网实时更新数据一直在变)

url2=‘https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=%2Fproduct_feed%2Frollup_threads%2Fv2%3Ffilter%3Dmarketplace(CN)%26filter%3Dlanguage(zh-Hans)%26filter%3DemployeePrice(true)%26filter%3DattributeIds(1c7c3d67-5d46-432d-9910-b1128d1b6503%2Ce09eabe9-5ff0-42af-b0a3-5f68af19d89a)%26anchor%3D24%26count%3D24%26consumerChannelId%3Dd9a5bc42-4b9c-4976-858a-f159cf99c647%26sort%3DproductInfo.merchPrice.currentPriceAsc’

url3=‘https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=%2Fproduct_feed%2Frollup_threads%2Fv2%3Ffilter%3Dmarketplace(CN)%26filter%3Dlanguage(zh-Hans)%26filter%3DemployeePrice(true)%26filter%3DattributeIds(1c7c3d67-5d46-432d-9910-b1128d1b6503%2Ce09eabe9-5ff0-42af-b0a3-5f68af19d89a)%26anchor%3D48%26count%3D24%26consumerChannelId%3Dd9a5bc42-4b9c-4976-858a-f159cf99c647%26sort%3DproductInfo.merchPrice.currentPriceAsc’

urls构建与objects获取


我们首先需要写递归函数获取所有urls

我们观察json内容就会发现我们需要的商品数据都在一个名为objects的key中 因此需要将所有objects放在一起

递归函数(核心函数)如下

#刚刚在调试台得到的初始地址

url1=‘https://www.nike.com/w/graphql?queryid=filteredProductsWithContext&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&uuids=1c7c3d67-5d46-432d-9910-b1128d1b6503,e09eabe9-5ff0-42af-b0a3-5f68af19d89a&language=zh-Hans&country=CN&sortBy=priceAsc’

#观察其他urls发现前面参数是一样的如下 我们先写前半部分

urlother=‘https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=’

urls=[url1]

#空list存放物品信息 观察发现json中的objects数据类型为list

pricedictlist=[]

#递归函数得到urls列表以及每个url中物品数据

def get_url_objcts(url=url1):

#首先得到初始url的json数据

response=requests.get(url)

#只取有用的数据内容 仔细观察json数据 得到下一个页面的next参数

#urllib.parse.quote(text)

按照标准, URL 只允许一部分 ASCII 字符(数字字母和部分符号),其他的字符(如汉字)是不符合 URL 标准的。

所以 URL 中使用其他字符就需要进行 URL 编码。

try:

nextpage_json=quote(response.json()[‘data’][‘filteredProductsWithContext’][‘pages’][‘next’])

#添加objects内容到列表

pricedictlist.extend(response.json()[‘data’][‘filteredProductsWithContext’][‘objects’])

except KeyError:

nextpage_json = quote(response.json()[‘data’][‘products’][‘pages’][‘next’])

添加objects内容到列表

pricedictlist.extend(response.json()[‘data’][‘products’][‘objects’])

except TypeError:

nextpage_json=‘’

#递归获取url与objects

if nextpage_json!=‘’:

urlnext=urlother+nextpage_json

urls.append(urlnext)

nextpage_json=‘’

get_url_objcts(urlnext)

#else只在不存在下一页时执行,相当于此时已经完成了objects的获取 下面构建发送信息

else:

i = 0

STR = str(‘https://www.nike.com/cn/w/nba-sleeveless-and-tank-tops-18iwiz9sbux?sort=priceAsc’)

compStr1 = ‘’

for each in pricedictlist:

title = each[‘publishedContent’][‘properties’][‘seo’]

if title == None:

continue

currentPrice = each[‘productInfo’][0][‘merchPrice’][‘currentPrice’]

fullPrice = each[‘productInfo’][0][‘merchPrice’][‘fullPrice’]

#只选取有用的数据 我们不要童装 同时只要打折商品

if (not re.search(‘童’, str(title[‘slug’]))) and (fullPrice != currentPrice):

i = i + 1

STR = STR + ‘\n\n’ + ((str(title[‘slug’]) + “\n” + " 原价" + str(fullPrice) + " 现价" + str(

currentPrice)) + ’ ’ + str(currentPrice * 100 / fullPrice) + ‘%’)

#发现每个商品名称后面都有独特的商品码为6个字母标识,所以切片记录下来用于对比

compStr1 = compStr1 + str(title[‘slug’][-6:])

STR = STR + ‘\n’ + (“本次数据一共:” + str(i) + “个”)

这之上 我们已经完成了数据的获取,接下来就是微信机器人发送了

itchat微信机器人


itchat是个人账户的开放源码wechat api项目,它使您可以通过命令行访问您的个人微信帐户。

如何向群发送消息?

import itchat

#登录微信网页版 参数enableCmdQR=0会出现图片二维码登录 为1则命令行窗口输出字符二维码 有的linux因为字符间距问题需要设置为2

itchat.auto_login(hotReload=0,enableCmdQR=0)

自己创建微信群,名称自定,并且要保存到通信录

chatroomName = ‘Money’ # 群名

itchat.get_chatrooms(update=True)

chatrooms = itchat.search_chatrooms(name=chatroomName)

print(compStr0)

if len(chatrooms) == 0:

print(‘没有找到群聊:’ + chatroomName)

exit(0)

else:

itchat.send_msg(‘hello world’, toUserName=chatrooms[0][‘UserName’]) # 发送消息

这就是简单的发送消息了,将我们上面的程序接合就可以实现微信发送了 还差一步,没错就是定时任务的问题

Python定时任务框架apscheduler


听名字就知道是干什么的 没错就是任务调度,我们可以使用这个库简洁的实现任务调度问题

简单例程如下:

from apscheduler.schedulers.blocking import BlockingScheduler

import time

scheduler = BlockingScheduler()

def job1():

print (“%s: 执行任务” % time.asctime())

scheduler.add_job(job1, ‘interval’, seconds=3)

scheduler.start()

程序送上~:


将环境配置好,直接放在自己的服务器就可以运行了,这一步就不再赘述

import re

import requests

from urllib.parse import quote

import itchat

from datetime import datetime

from apscheduler.schedulers.blocking import BlockingScheduler

#登录微信网页版 参数enableCmdQR=0会出现图片二维码登录 为1则命令行窗口输出字符二维码 有的linux因为字符间距问题需要设置为2

itchat.auto_login(hotReload=0,enableCmdQR=2)

#比较字符串,用于判断是否更新数据

compStr0=‘fuckkkkkkkkkkkkkkkk’

def main():

#刚刚在调试台得到的初始地址

url1=‘https://www.nike.com/w/graphql?queryid=filteredProductsWithContext&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&uuids=1c7c3d67-5d46-432d-9910-b1128d1b6503,e09eabe9-5ff0-42af-b0a3-5f68af19d89a&language=zh-Hans&country=CN&sortBy=priceAsc’

#观察其他urls发现前面参数是一样的如下 我们先写前半部分

urlother=‘https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=’

urls=[url1]

#空list存放物品信息 观察发现json中的objects数据类型为list

pricedictlist=[]

#递归函数得到urls列表以及每个url中物品数据

def get_url_objcts(url=url1):

#首先得到初始url的json数据

response=requests.get(url)

#只取有用的数据内容 仔细观察json数据 得到下一个页面的next参数

#urllib.parse.quote(text)

按照标准, URL 只允许一部分 ASCII 字符(数字字母和部分符号),其他的字符(如汉字)是不符合 URL 标准的。

所以 URL 中使用其他字符就需要进行 URL 编码。

try:

nextpage_json=quote(response.json()[‘data’][‘filteredProductsWithContext’][‘pages’][‘next’])

pricedictlist.extend(response.json()[‘data’][‘filteredProductsWithContext’][‘objects’])

except KeyError:

nextpage_json = quote(response.json()[‘data’][‘products’][‘pages’][‘next’])

pricedictlist.extend(response.json()[‘data’][‘products’][‘objects’])

except TypeError:

nextpage_json=‘’

#递归获取url与objects

if nextpage_json!=‘’:

urlnext=urlother+nextpage_json

urls.append(urlnext)

nextpage_json=‘’

get_url_objcts(urlnext)

#else只在不存在下一页时执行,相当于此时已经完成了objects的获取
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

…(img-4lMn8Tr0-1713610947848)]

[外链图片转存中…(img-5GOenEB7-1713610947849)]

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值