본문 바로가기

전산쟁이의 하루

파이썬으로 잔여백신 매크로 만들기

0. 설치환경 - 파이참 사용

 

1. 오픈소스로 공유된 소스를 약간 수정했습니다.

 

출처 : https://github.com/kimytsc/covid-rest-vaccine-macro

 

2. 크롬에서 네이버 인증을 해도 잔여백신 예약창으로 이동이 안됨

 

3. 네이버웨일을 기본브라우저로 설정 & 인증서를 미리 받아놓으면 웨일에서 자동예약이 돌아감

 

 

5. 네이버 플레이스의 X,Y,bounds 좌표코드를 수정합니다.

 

아래의 소스코드에서 주석참조

import pyautogui
import requests
import json
import urllib3
import os
import time
import datetime
import webbrowser
urllib3.disable_warnings()


APIURL = 'https://api.place.naver.com/graphql'
# 코로나 백신의료기관 옆에 x,y 좌표를 수정합니다.
# APIdata의 mobile x,y 축은 앞줄에 입력한 x,y 좌표값을 넣고 bounds 값을 수정 합니다.
APIdata = '[{"operationName":"vaccineList","variables":{"input":{"keyword":"코로나백신위탁의료기관","x":"128.921659","y":"35.1789156"},' \
          '"businessesInput":{"start":0,"display":100,"deviceType":"mobile","x":"128.921659","y":"35.1789156","bounds":"128.7683654;35.0833093;129.0749526;35.2744096","sortingOrder":"distance"},' \
          '"isNmap":false,"isBounds":false},"query":"query vaccineList($input: RestsInput, $businessesInput: RestsBusinessesInput, $isBounds: Boolean!) ' \
          '{  rests(input: $input) {    businesses(input: $businessesInput) {      total      vaccineLastSave      isUpdateDelayed      items ' \
          '{        id        name        description        distance        commonAddress        roadAddress        address        imageUrl        imageCount        tags        distance        category        businessHours        vaccineOpeningHour {          isDayOff          standardTime          __typename        }        vaccineQuantity {          totalQuantity          totalQuantityStatus          startTime          endTime          vaccineOrganizationCode          list {            quantity            quantityStatus            vaccineType            __typename          }          __typename        }        __typename      }      optionsForMap @include(if: $isBounds) {        maxZoom        minZoom        includeMyLocation        maxIncludePoiCount        center        __typename      }      __typename    }    queryResult {      keyword      vaccineFilter      categories      region      isBrandList      filterBooking      hasNearQuery      isPublicMask      __typename    }    __typename  }}"}]'

done = False
while done == False:
    time.sleep(0.3)
    headers = {
        "Origin": "https://m.place.naver.com",
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
        "Content-Type": "application/json",
        "Referer": "https://m.place.naver.com/rest/vaccine",
    }

    response = requests.post(APIURL, APIdata.encode('utf-8'), headers=headers)
    if response.status_code != 200:
      # print(response.text)
      exit()
    #print("position : ", pyautogui.position())
    received_API_status_code = response.status_code
    received_API_data = response.text

    print(received_API_data)
    print(datetime.datetime.now())

    jsonloaded = json.loads(received_API_data)
    # print(jsonloaded[0]["data"]["rests"]["businesses"]["items"])
    jsonData = jsonloaded[0]["data"]["rests"]["businesses"]["items"]
    found = False
    for x in jsonData:
      # print(x)
      if x['vaccineQuantity'] and int(x['vaccineQuantity']['totalQuantity']) > 0:
        # 화이자 or 모더나 있는지 체크
        for y in x["vaccineQuantity"]["list"]:
            if (y.get('vaccineType') == "화이자" or y.get('vaccineType') == "모더나") and y.get("quantity") > 0:
                found = x
                #print(y.get("quantity"))
                done = True
                break
        if done:
          break
        # keys = x.keys()
        # print(keys)
        # values = x.values()
        # print(values)

print("--- found")
#print(found.keys())
#print(found.values())
orgCdCode = x.get('vaccineQuantity').get('vaccineOrganizationCode')
sid = x.get('id')
url = '"https://v-search.nid.naver.com/reservation/standby?orgCd=' + orgCdCode + '&sid=' + sid + '"'
#기본브라우저를 네이버 웨일로 설정하고 브라우저 내에 네이버 인증서를 인증합니다. 네이버 지갑 앱 설치 필요
webbrowser.open(url)
pyautogui.click(x=850, y=1020, button="left", clicks=10, interval=0.5)
print('"https://v-search.nid.naver.com/reservation/standby?orgCd=' + orgCdCode + '&sid=' + sid + '"')

 

6. 웨일 페이지는 전체화면으로 해두는걸 추천합니다.

 

7. 실패시에 while문을 재실행 해줘야하므로 저는 그냥 재시작 버튼 눌렀습니다.

 

8. 37번만의 자동예약 시도 끝에 성공....