看看输出什么:
这样看起来好多了,好的 似乎到这里我们已经可以开始选取我们需要的数据进行记录了,但是我们又会注意到一点,这个网页的内容是瀑布流方式,也就是说滚轮往下滚动才会有更多的数据出现,可是我们目前只获取了这个页面最上端的数据,如果我们想获取更多的数据怎么办?
我们还是使用调试台,其实他页面只要变化,网站交互一定是有活动的,所以我们现在就观察当滚轮往下滚动到瀑布流下端时调试台会出现什么东西就可以了
往下滚动,发现调试台确实出现了很多新的文件,我们猜想这些文件中一定有瀑布流下端的数据,对了还记得我们刚才找到的文件名是什么吗?对的,是名称为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
我们观察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是个人账户的开放源码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’]) # 发送消息
这就是简单的发送消息了,将我们上面的程序接合就可以实现微信发送了 还差一步,没错就是定时任务的问题
听名字就知道是干什么的 没错就是任务调度,我们可以使用这个库简洁的实现任务调度问题
简单例程如下:
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()
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。
别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。
我先来介绍一下这些东西怎么用,文末抱走。
(1)Python所有方向的学习路线(新版)
这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
最近我才对这些路线做了一下新的更新,知识体系更全面了。
(2)Python学习视频
包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。
(3)100多个练手项目
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。
(4)200多本电子书
这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。
基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。
(5)Python知识点汇总
知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。
(6)其他资料
还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。
这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。
这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-RvE1fP2j-1712699168084)]