日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器

系統(tǒng) 1783 0

寫在最前

  程序是為人類服務(wù)的,最近正好身邊小伙伴們?cè)谧銮蛞律猓?dāng)然是去nikenba專區(qū)購(gòu)買了,可是有些熱門球衣發(fā)布幾分鐘就被搶完,有些折扣球衣也是很快就被搶售一空,那么我們只能靠自己的眼睛一直盯著網(wǎng)站嗎?NoNoNo,作為計(jì)算機(jī)專業(yè)的學(xué)生,怎么能為這種事情浪費(fèi)時(shí)間呢?那肯定想法就是寫爬蟲(chóng)自動(dòng)比對(duì)價(jià)格啊,后來(lái)又在想,爬蟲(chóng)數(shù)據(jù)也是在PC端啊,該怎么實(shí)時(shí)提醒我們呢?再弄一個(gè)微信機(jī)器人發(fā)送數(shù)據(jù)不就可以了嗎?說(shuō)干就干,代碼開(kāi)擼

先看下效果:

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第1張圖片

準(zhǔn)備工作:

首先本文使用py3,需要安裝以下庫(kù):

1)itchat

2)requests

3)apscheduler

分析網(wǎng)頁(yè):

首先我們需要做什么?毫無(wú)疑問(wèn),分析網(wǎng)頁(yè),因?yàn)樽钪匾囊徊骄褪谦@取數(shù)據(jù),那么如何獲取數(shù)據(jù)就是我們首先要克服的困難

附上 nike nba專區(qū)地址:https://www.nike.com/cn/w/nba-sleeveless-and-tank-tops-18iwiz9sbux

首先我們要明確一個(gè)地方,我們的目的是實(shí)時(shí)監(jiān)控?zé)衢T打折球衣,所以我們的價(jià)格肯定首先降序排列,不過(guò)先不用著急,打開(kāi)F12先看下調(diào)試器,對(duì)了我使用的是chrome瀏覽器

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第2張圖片

由于我們是先打開(kāi)網(wǎng)頁(yè)再打開(kāi)調(diào)試窗口,所以目前我們看不到數(shù)據(jù),別急,我們刷新一下再看

哦吼,完蛋,怎么這么多東西貌似根本沒(méi)法看

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第3張圖片

別急 繼續(xù)分析,作為一個(gè)學(xué)(qiong)生(bi),我們肯定先關(guān)注價(jià)格了,當(dāng)然要升序排列啊!

好的 點(diǎn)下瀏覽器調(diào)試窗口中的清除按鈕(就是下面這個(gè)藍(lán)色標(biāo)記的按鈕)先清除下調(diào)試臺(tái)中的數(shù)據(jù) 然后呢我們點(diǎn)下篩選方式價(jià)格由低到高(紅色標(biāo)記的菜單鍵中選擇)

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第4張圖片

得到調(diào)試臺(tái)如下,完蛋了還是一堆怎么辦?

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第5張圖片

沒(méi)關(guān)系,至少現(xiàn)在網(wǎng)頁(yè)內(nèi)容已經(jīng)是按照價(jià)格升序排列了,我們?cè)賮?lái)看看得到的Network數(shù)據(jù),挨個(gè)點(diǎn)一點(diǎn)看看,發(fā)現(xiàn)當(dāng)點(diǎn)到名稱為graphql開(kāi)頭的文件里去時(shí)候,有東西出現(xiàn)了

里面的響應(yīng)內(nèi)容出現(xiàn)了幾個(gè)熟悉的隊(duì)名稱和球員名稱甚至還有價(jià)格,等等,這不就是我們要的數(shù)據(jù)嗎?

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第6張圖片

看來(lái)我們找對(duì)了地方,我們雙擊點(diǎn)開(kāi)graphql開(kāi)頭的網(wǎng)頁(yè)文件看看會(huì)有什么呢? 。。。 看起來(lái)雜亂無(wú)章,但是貌似確實(shí)是我們要的數(shù)據(jù),是json格式的

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第7張圖片

在網(wǎng)頁(yè)上看json簡(jiǎn)直是折磨,好的,我們用python開(kāi)始把這個(gè)網(wǎng)頁(yè)內(nèi)容給弄下來(lái)仔細(xì)研究下

pycharm開(kāi)搞

            
              import
            
            
               requests

            
            
              import
            
            
               json


            
            
              #
            
            
              剛剛在調(diào)試臺(tái)得到的地址
            
            
url=
            
              '
            
            
              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
            
            
              '
            
            
              #
            
            
              使json數(shù)據(jù)格式化輸出更好觀察
            
            
              def
            
            
               better_jsprint(json_obj):
    
            
            
              #
            
            
               使用indent=4 這個(gè)參數(shù)對(duì)json進(jìn)行數(shù)據(jù)格式化輸出
            
            
              #
            
            
              因?yàn)閖son.dumps 序列化時(shí)對(duì)中文默認(rèn)使用的ascii編碼.想輸出真正的中文需要指定ensure_ascii=False
            
            
              return
            
             json.dumps(json.loads(json_obj),indent=4,ensure_ascii=
            
              False)

response
            
            =
            
              requests.get(url)


            
            
              print
            
            (better_jsprint(response.text))
          

看看輸出什么:

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第8張圖片

這樣看起來(lái)好多了,好的 似乎到這里我們已經(jīng)可以開(kāi)始選取我們需要的數(shù)據(jù)進(jìn)行記錄了,但是我們又會(huì)注意到一點(diǎn),這個(gè)網(wǎng)頁(yè)的內(nèi)容是瀑布流方式,也就是說(shuō)滾輪往下滾動(dòng)才會(huì)有更多的數(shù)據(jù)出現(xiàn),可是我們目前只獲取了這個(gè)頁(yè)面最上端的數(shù)據(jù),如果我們想獲取更多的數(shù)據(jù)怎么辦?

我們還是使用調(diào)試臺(tái),其實(shí)他頁(yè)面只要變化,網(wǎng)站交互一定是有活動(dòng)的,所以我們現(xiàn)在就觀察當(dāng)滾輪往下滾動(dòng)到瀑布流下端時(shí)調(diào)試臺(tái)會(huì)出現(xiàn)什么東西就可以了

往下滾動(dòng),發(fā)現(xiàn)調(diào)試臺(tái)確實(shí)出現(xiàn)了很多新的文件,我們猜想這些文件中一定有瀑布流下端的數(shù)據(jù),對(duì)了還記得我們剛才找到的文件名是什么嗎?對(duì)的,是名稱為graphql開(kāi)頭的文件,那么會(huì)不會(huì)新的數(shù)據(jù)文件也是這個(gè)名字開(kāi)頭的呢?我們使用調(diào)試臺(tái)搜索下看看

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第9張圖片

來(lái)了來(lái)了,它真的出現(xiàn)了,現(xiàn)在出現(xiàn)了3個(gè)文件都是graphql名字開(kāi)頭,毫無(wú)疑問(wèn)第一個(gè)文件是我們上面找到的,那么第二個(gè)第三個(gè)呢? 我們點(diǎn)開(kāi)看看,會(huì)發(fā)現(xiàn)對(duì)應(yīng)的商品名稱之類的真的是瀑布流下端的數(shù)據(jù)。

OK看起來(lái)我們現(xiàn)在確實(shí)得到了所有數(shù)據(jù)文件的url

我最初的想法是直接將3個(gè)url寫到一個(gè)列表中然后使用循環(huán)讀取如下圖(其實(shí)會(huì)發(fā)現(xiàn)第二個(gè)url與第三個(gè)看起來(lái)貌似一樣啊怎么回事?下面有解釋別急)

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第10張圖片

后來(lái)呢我突然意識(shí)到,萬(wàn)一商品更多了怎么辦?會(huì)不會(huì)出現(xiàn)4個(gè)5個(gè)url?而總不能每次都靠人力去數(shù)有多少個(gè)url吧?然后就想,怎樣才能讓程序自動(dòng)添加url呢?

我們?cè)倩仡^看看第一次抓取下來(lái)的 url1 的json數(shù)據(jù),首先嘗試下檢索page這個(gè)關(guān)鍵詞(畢竟一般程序員都會(huì)寫這個(gè)作為頁(yè)面標(biāo)識(shí)吧?),哦霍,發(fā)現(xiàn)了了不得的東西,

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第11張圖片

這些數(shù)據(jù)看起來(lái)很眼熟啊,還有uuids?再比對(duì)下第一次抓的 url1 發(fā)現(xiàn)里面的uuids還真的就是json里面的數(shù)據(jù),那么又看到pages里面有個(gè)next 納尼?這會(huì)不會(huì)是瀑布流下半部分url組成呢?快來(lái)比對(duì) 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中的內(nèi)容,發(fā)現(xiàn)真的存在與endpoint參數(shù)后面,哦霍 現(xiàn)在我們猜想,會(huì)不會(huì)每個(gè)json中都包含pages next這個(gè)數(shù)據(jù)

打印url2繼續(xù)檢索pages的next?

真的存在,并且還存在prev參數(shù)(前一頁(yè)),說(shuō)明我們的猜想可能是正確的,這時(shí)候細(xì)心的小伙伴可能發(fā)現(xiàn)了 url2中的next內(nèi)容與url1中一致啊,哦原來(lái)是這樣,這樣才導(dǎo)致了我們剛剛調(diào)試臺(tái)中出現(xiàn)3個(gè)url文件但是第二個(gè)與第三個(gè)一樣的情況

但是我們猜想第三個(gè)url返回?cái)?shù)據(jù)中應(yīng)該沒(méi)有next否則就應(yīng)該出現(xiàn)第四個(gè)文件了,我們來(lái)試一試

在url3返回?cái)?shù)據(jù)中檢索next

python+爬蟲(chóng)+微信機(jī)器人 打造屬于你的網(wǎng)購(gòu)價(jià)格監(jiān)督利器_第12張圖片

真的為空了所以我們可以確定,只要瀑布流下方仍有數(shù)據(jù),那么一定存在next參數(shù) 因此我們可以確定瀑布流url寫法 我們網(wǎng)頁(yè)分析完成 接下來(lái)就要進(jìn)行真正的代碼編寫了

(其實(shí)我有一個(gè)疑問(wèn) url2與url3看起來(lái)確實(shí)是一模一樣的并且我嘗試做了差值運(yùn)算,發(fā)現(xiàn)還是一樣的,但是返回?cái)?shù)據(jù)確實(shí)不同,有大神可以發(fā)現(xiàn)這兩個(gè)url不同之處嗎 下面放上這兩個(gè)url)

(url已改變,根據(jù)官網(wǎng)實(shí)時(shí)更新數(shù)據(jù)一直在變)

            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構(gòu)建與objects獲取

我們首先需要寫遞歸函數(shù)獲取所有urls

我們觀察json內(nèi)容就會(huì)發(fā)現(xiàn)我們需要的商品數(shù)據(jù)都在一個(gè)名為objects的key中 因此需要將所有objects放在一起

遞歸函數(shù)(核心函數(shù))如下

            
              #
            
            
              剛剛在調(diào)試臺(tái)得到的初始地址
            
            
    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發(fā)現(xiàn)前面參數(shù)是一樣的如下 我們先寫前半部分
            
            
    urlother=
            
              '
            
            
              https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=
            
            
              '
            
            
              
    urls
            
            =
            
              [url1]

    
            
            
              #
            
            
              空l(shuí)ist存放物品信息 觀察發(fā)現(xiàn)json中的objects數(shù)據(jù)類型為list
            
            
    pricedictlist=
            
              []

    
            
            
              #
            
            
              遞歸函數(shù)得到urls列表以及每個(gè)url中物品數(shù)據(jù)
            
            
              def
            
             get_url_objcts(url=
            
              url1):
        
            
            
              #
            
            
              首先得到初始url的json數(shù)據(jù)
            
            
        response=
            
              requests.get(url)
        
            
            
              #
            
            
              只取有用的數(shù)據(jù)內(nèi)容 仔細(xì)觀察json數(shù)據(jù) 得到下一個(gè)頁(yè)面的next參數(shù)
            
            
              #
            
            
              urllib.parse.quote(text)
            
            
              #
            
            
               按照標(biāo)準(zhǔn), URL 只允許一部分 ASCII 字符(數(shù)字字母和部分符號(hào)),其他的字符(如漢字)是不符合 URL 標(biāo)準(zhǔn)的。
            
            
              #
            
            
               所以 URL 中使用其他字符就需要進(jìn)行 URL 編碼。
            
            
              try
            
            
              :
            nextpage_json
            
            =quote(response.json()[
            
              '
            
            
              data
            
            
              '
            
            ][
            
              '
            
            
              filteredProductsWithContext
            
            
              '
            
            ][
            
              '
            
            
              pages
            
            
              '
            
            ][
            
              '
            
            
              next
            
            
              '
            
            
              ])
            
            
            
              #
            
            
              添加objects內(nèi)容到列表
            
            
            pricedictlist.extend(response.json()[
            
              '
            
            
              data
            
            
              '
            
            ][
            
              '
            
            
              filteredProductsWithContext
            
            
              '
            
            ][
            
              '
            
            
              objects
            
            
              '
            
            
              ])
        
            
            
              except
            
            
               KeyError:
            nextpage_json 
            
            = quote(response.json()[
            
              '
            
            
              data
            
            
              '
            
            ][
            
              '
            
            
              products
            
            
              '
            
            ][
            
              '
            
            
              pages
            
            
              '
            
            ][
            
              '
            
            
              next
            
            
              '
            
            
              ])
            
            
            
              #
            
            
               添加objects內(nèi)容到列表
            
            
            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只在不存在下一頁(yè)時(shí)執(zhí)行,相當(dāng)于此時(shí)已經(jīng)完成了objects的獲取 下面構(gòu)建發(fā)送信息
            
            
              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
            
            
              '
            
            
              ]
                
            
            
              #
            
            
              只選取有用的數(shù)據(jù) 我們不要童裝 同時(shí)只要打折商品
            
            
              if
            
             (
            
              not
            
             re.search(
            
              '
            
            
            
              '
            
            , str(title[
            
              '
            
            
              slug
            
            
              '
            
            ]))) 
            
              and
            
             (fullPrice !=
            
               currentPrice):
                    i 
            
            = i + 1
            
              
                    STR 
            
            = STR + 
            
              '
            
            
              \n\n
            
            
              '
            
             + ((str(title[
            
              '
            
            
              slug
            
            
              '
            
            ]) + 
            
              "
            
            
              \n
            
            
              "
            
             + 
            
              "
            
            
                原價(jià)
            
            
              "
            
             + str(fullPrice) + 
            
              "
            
            
                現(xiàn)價(jià)
            
            
              "
            
             +
            
               str(
                        currentPrice)) 
            
            + 
            
              '
            
            
              '
            
             + str(currentPrice * 100 / fullPrice) + 
            
              '
            
            
              %
            
            
              '
            
            
              )
                    
            
            
              #
            
            
              發(fā)現(xiàn)每個(gè)商品名稱后面都有獨(dú)特的商品碼為6個(gè)字母標(biāo)識(shí),所以切片記錄下來(lái)用于對(duì)比
            
            
                    compStr1 = compStr1 + str(title[
            
              '
            
            
              slug
            
            
              '
            
            ][-6
            
              :])

            STR 
            
            = STR + 
            
              '
            
            
              \n
            
            
              '
            
             + (
            
              "
            
            
              本次數(shù)據(jù)一共:
            
            
              "
            
             + str(i) + 
            
              "
            
            
              個(gè)
            
            
              "
            
            )
          

這之上 我們已經(jīng)完成了數(shù)據(jù)的獲取,接下來(lái)就是微信機(jī)器人發(fā)送了

itchat微信機(jī)器人

itchat是個(gè)人賬戶的開(kāi)放源碼wechat api項(xiàng)目, 它使您可以通過(guò)命令行訪問(wèn)您的個(gè)人微信帳戶。

如何向群發(fā)送消息?

            
              import
            
            
               itchat

            
            
              #
            
            
              登錄微信網(wǎng)頁(yè)版 參數(shù)enableCmdQR=0會(huì)出現(xiàn)圖片二維碼登錄 為1則命令行窗口輸出字符二維碼 有的linux因?yàn)樽址g距問(wèn)題需要設(shè)置為2
            
            
itchat.auto_login(hotReload=0,enableCmdQR=
            
              0)


            
            
              #
            
            
               自己創(chuàng)建微信群,名稱自定,并且要保存到通信錄
            
            
chatroomName = 
            
              '
            
            
              Money
            
            
              '
            
            
              #
            
            
               群名
            
            
itchat.get_chatrooms(update=
            
              True)
chatrooms 
            
            = itchat.search_chatrooms(name=
            
              chatroomName)

            
            
              #
            
            
               print(compStr0)
            
            
              if
            
             len(chatrooms) ==
            
               0:
    
            
            
              #
            
            
               print('沒(méi)有找到群聊:' + chatroomName)
            
            
                  exit(0)

            
            
              else
            
            
              :
    itchat.send_msg(
            
            
              '
            
            
              hello world
            
            
              '
            
            , toUserName=chatrooms[0][
            
              '
            
            
              UserName
            
            
              '
            
            ])  
            
              #
            
            
               發(fā)送消息
            
          

這就是簡(jiǎn)單的發(fā)送消息了,將我們上面的程序接合就可以實(shí)現(xiàn)微信發(fā)送了 還差一步,沒(méi)錯(cuò)就是定時(shí)任務(wù)的問(wèn)題

Python定時(shí)任務(wù)框架apscheduler

聽(tīng)名字就知道是干什么的 沒(méi)錯(cuò)就是任務(wù)調(diào)度,我們可以使用這個(gè)庫(kù)簡(jiǎn)潔的實(shí)現(xiàn)任務(wù)調(diào)度問(wèn)題

簡(jiǎn)單例程如下:

            
              from
            
             apscheduler.schedulers.blocking 
            
              import
            
            
               BlockingScheduler

            
            
              import
            
            
               time
scheduler 
            
            =
            
               BlockingScheduler()

            
            
              def
            
            
               job1():
 
            
            
              print
            
             (
            
              "
            
            
              %s: 執(zhí)行任務(wù)
            
            
              "
            
             %
            
               time.asctime())
scheduler.add_job(job1, 
            
            
              '
            
            
              interval
            
            
              '
            
            , seconds=3
            
              )
scheduler.start()
            
          

輸出:

            Mon Aug 19 18:35:52 2019
            
              : 執(zhí)行任務(wù)
Mon Aug 
            
            19 18:35:55 2019
            
              : 執(zhí)行任務(wù)
Mon Aug 
            
            19 18:35:58 2019
            
              : 執(zhí)行任務(wù)
Mon Aug 
            
            19 18:36:01 2019
            
              : 執(zhí)行任務(wù)
Mon Aug 
            
            19 18:36:04 2019
            
              : 執(zhí)行任務(wù)
Mon Aug 
            
            19 18:36:07 2019
            
              : 執(zhí)行任務(wù)
Mon Aug 
            
            19 18:36:10 2019: 執(zhí)行任務(wù)
          

最后一步就是將上面講的所有來(lái)一個(gè)大集合

程序送上~:

將環(huán)境配置好,直接放在自己的服務(wù)器就可以運(yùn)行了,這一步就不再贅述

            
              import
            
            
               re

            
            
              import
            
            
               requests

            
            
              from
            
             urllib.parse 
            
              import
            
            
               quote

            
            
              import
            
            
               itchat

            
            
              from
            
             datetime 
            
              import
            
            
               datetime

            
            
              from
            
             apscheduler.schedulers.blocking 
            
              import
            
            
               BlockingScheduler


            
            
              #
            
            
              登錄微信網(wǎng)頁(yè)版 參數(shù)enableCmdQR=0會(huì)出現(xiàn)圖片二維碼登錄 為1則命令行窗口輸出字符二維碼 有的linux因?yàn)樽址g距問(wèn)題需要設(shè)置為2
            
            
itchat.auto_login(hotReload=0,enableCmdQR=
            
              2)


            
            
              #
            
            
              比較字符串,用于判斷是否更新數(shù)據(jù)
            
            
compStr0=
            
              '
            
            
              fuckkkkkkkkkkkkkkkk
            
            
              '
            
            
              def
            
            
               main():
    
            
            
              #
            
            
              剛剛在調(diào)試臺(tái)得到的初始地址
            
            
    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發(fā)現(xiàn)前面參數(shù)是一樣的如下 我們先寫前半部分
            
            
    urlother=
            
              '
            
            
              https://www.nike.com/w/graphql?queryid=products&anonymousId=A54CD5202A87B54B4415AD4BC11E5692&endpoint=
            
            
              '
            
            
              
    urls
            
            =
            
              [url1]

    
            
            
              #
            
            
              空l(shuí)ist存放物品信息 觀察發(fā)現(xiàn)json中的objects數(shù)據(jù)類型為list
            
            
    pricedictlist=
            
              []

    
            
            
              #
            
            
              遞歸函數(shù)得到urls列表以及每個(gè)url中物品數(shù)據(jù)
            
            
              def
            
             get_url_objcts(url=
            
              url1):
        
            
            
              #
            
            
              首先得到初始url的json數(shù)據(jù)
            
            
        response=
            
              requests.get(url)
        
            
            
              #
            
            
              只取有用的數(shù)據(jù)內(nèi)容 仔細(xì)觀察json數(shù)據(jù) 得到下一個(gè)頁(yè)面的next參數(shù)
            
            
              #
            
            
              urllib.parse.quote(text)
            
            
              #
            
            
               按照標(biāo)準(zhǔn), URL 只允許一部分 ASCII 字符(數(shù)字字母和部分符號(hào)),其他的字符(如漢字)是不符合 URL 標(biāo)準(zhǔn)的。
            
            
              #
            
            
               所以 URL 中使用其他字符就需要進(jìn)行 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只在不存在下一頁(yè)時(shí)執(zhí)行,相當(dāng)于此時(shí)已經(jīng)完成了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
            
            
              '
            
            
              ]
                
            
            
              #
            
            
              只選取有用的數(shù)據(jù) 我們不要童裝 同時(shí)只要打折商品
            
            
              if
            
             (
            
              not
            
             re.search(
            
              '
            
            
            
              '
            
            , str(title[
            
              '
            
            
              slug
            
            
              '
            
            ]))) 
            
              and
            
             (fullPrice !=
            
               currentPrice):
                    i 
            
            = i + 1
            
              
                    STR 
            
            = STR + 
            
              '
            
            
              \n\n
            
            
              '
            
             + ((str(title[
            
              '
            
            
              slug
            
            
              '
            
            ]) + 
            
              "
            
            
              \n
            
            
              "
            
             + 
            
              "
            
            
                原價(jià)
            
            
              "
            
             + str(fullPrice) + 
            
              "
            
            
                現(xiàn)價(jià)
            
            
              "
            
             +
            
               str(
                        currentPrice)) 
            
            + 
            
              '
            
            
              '
            
             + str(currentPrice * 100 / fullPrice) + 
            
              '
            
            
              %
            
            
              '
            
            
              )
                    
            
            
              #
            
            
              發(fā)現(xiàn)每個(gè)商品名稱后面都有獨(dú)特的商品碼為6個(gè)字母標(biāo)識(shí),所以切片記錄下來(lái)用于對(duì)比
            
            
                    compStr1 = compStr1 + str(title[
            
              '
            
            
              slug
            
            
              '
            
            ][-6
            
              :])

            STR 
            
            = STR + 
            
              '
            
            
              \n
            
            
              '
            
             + (
            
              "
            
            
              本次數(shù)據(jù)一共:
            
            
              "
            
             + str(i) + 
            
              "
            
            
              個(gè)
            
            
              "
            
            
              )

            
            
            
              #
            
            
              自己創(chuàng)建微信群,名稱自定
            
            
            chatroomName = 
            
              '
            
            
              Money
            
            
              '
            
            
              #
            
            
               群名
            
            
            itchat.get_chatrooms(update=
            
              True)
            chatrooms 
            
            = itchat.search_chatrooms(name=
            
              chatroomName)
            
            
            
              global
            
            
               compStr0
            
            
            
              #
            
            
               print(compStr0)
            
            
              if
            
             len(chatrooms) ==
            
               0:
                
            
            
              #
            
            
               print('沒(méi)有找到群聊:' + chatroomName)
            
            
                              exit(0)
            
            
            
              else
            
            
              :
                
            
            
              #
            
            
              判斷數(shù)據(jù)是否變化
            
            
              if
            
             (compStr1 !=
            
               compStr0):
                    itchat.send_msg(STR, toUserName
            
            =chatrooms[0][
            
              '
            
            
              UserName
            
            
              '
            
            ])  
            
              #
            
            
               發(fā)送消息
            
            
                    compStr0 =
            
               compStr1
            
            
            
              #
            
            
               print(compStr0)
            
            
                  get_url_objcts()


sched 
            
            =
            
               BlockingScheduler()

            
            
              #
            
            
               任務(wù)調(diào)度 每2分鐘觸發(fā) 時(shí)間自定
            
            
sched.add_job(main, 
            
              '
            
            
              interval
            
            
              '
            
            , minutes=2, next_run_time=
            
              datetime.now())
sched.start()

itchat.run()
            
          

轉(zhuǎn)載請(qǐng)注明出處 thank you!

?


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 晋宁县| 成安县| 栾城县| 长泰县| 华安县| 晋中市| 信阳市| 兴文县| 安化县| 色达县| 湘阴县| 西林县| 马鞍山市| 乳山市| 梅河口市| 怀集县| 阿巴嘎旗| 谢通门县| 英山县| 绍兴市| 镇远县| 赤峰市| 东莞市| 蕉岭县| 梨树县| 遵义县| 永修县| 从江县| 介休市| 密云县| 伊春市| 张家川| 焉耆| 二连浩特市| 合水县| 德昌县| 保山市| 讷河市| 措美县| 增城市| 吴川市|