제가 6년 동안 음식을 운송한 경험을 분석해 봤어요.

13053 단어 bashdatasqlcoding
식품 배달 앱이 나오기 전에 온라인으로 식품을 주문하는 것은 고통스러운 일이다.2016년에 저는 인도 식품 배달 앱Swiggy을 사용하기 시작했습니다. 음식 배달을 너무 쉽게 하기 때문에 주문이 최고조에 달했습니다.나는 내가 얼마와 무엇을 주문했는지 분석하고 싶다. 재미있을 것이다.
이 문장은 두 가지 부분이 있다. a) 내가 어떻게 했지?b) 숫자와 나의 분석.너의 취미에 따라 너는 그중의 하나를 뛰어넘을 수 있다.

내가 어떻게 했지?


Swiggy에서 개인 데이터를 가져올 API가 없습니다.그러나, 과거의 주문서를 보여 주는 페이지가 있습니다.문제는 한 번에 다섯 개의 주문서만 표시할 수 있고, '더 많은 주문 보이기' 를 눌러야 되돌아갈 수 있다는 것이다.물론, 너는 반드시 어떤 방식으로 자동화를 실현해야 한다.

데이터 출처를 찾아내다



주문 페이지 XHR
나는 이 응용 프로그램의 인터넷 버전에 처음 로그인했다. 왜냐하면 그것은 그곳의 요청을 비교적 쉽게 분석할 수 있기 때문이다.주문 페이지가 URL/dapi/order/all?order_id=$$ORDER_ID$$에 페이지별 주문$$ORDER_ID$$을 받기 위해 XHR 요청을 보낸 것 같습니다.

주문 페이지 응답
응답은 많은 필드를 포함하는 JSON 객체 배열입니다.
우리는 응답의 어느 부분을 사용해야 하는지 알 필요가 없다. 왜냐하면 우리는 그것을 모두 저장해서 잠시 후에 처리할 수 있기 때문이다.
나는 Postgres를 사용하여 이 데이터를 저장할 것이다. 왜냐하면 a) 이 정상적으로 작동할 수 있기 때문이다. b) 는 JSON 조회를 매우 지원한다.Postgres app를 통해 Mac 컴퓨터에 로컬로 Postgres를 설치하는 것은 매우 간단하다.
다음은 제가 사용할 모드입니다.
CREATE TABLE swiggy (
    order_id text PRIMARY KEY,
    data jsonb
);
왜 우리는 2열만 필요합니까?order_id는 모든 주문서를 유일하게 표시할 수 있기 때문에 data열에서 우리는 전체 대상을 저장할 수 있다.앞서 말씀드린 바와 같이 Postgres는 JSON 조회를 매우 쉽게 합니다.

데이터 가져오기


데이터를 가져오겠습니다!나는 bash를 사용하여 이 점을 실현할 것이다."펑??? 아, 왜?"물어봐도 돼.나는 과거에 bash에 대해서도 비슷한 혐오감을 느꼈지만, 지난 1년 동안, 나는 네가 요령을 터득하면 어떤 일을 하기가 매우 쉬워질 것이라는 것을 깨달았다.
만약 당신이 다른 방법을 사용하고 싶다면, 이것은 매우 좋은 것이다. 왜냐하면 기본적인 사상은 휴대하기 매우 편리하기 때문이다.예를 들어 axios 대신 cURL를 사용한다.
첫째, 기본 요구.우리는 간단한 주문 요청이 유효한지 확인해야 한다.가장 간단한 방법은 개발자의 컨트롤러에서 'cURL로 복사' 요청을 하고 터미널에서 실행하는 것입니다.
만약 성공한다면 정말 다행이다!제목, 사용자 에이전트, 쿠키 추적 등 필요하지 않은 인자를 삭제할 수 있습니다.내가 수정을 마친 후 주문을 받은 기본적인 요구는 다음과 같다.
curl -sL "https://www.swiggy.com/dapi/order/all?order_id=$next_order_id" \
     -H "cookie: _session_tid=$SESSION_ID"
그중$SESSION_ID은 첫 번째 화면 캡처에서 볼 수 있는 긴 매개 변수다.
요청이 성공하면 JSON을 분석하고 jq 스트리밍 대상을 사용할 수 있습니다.
IFS=$'\n'
for order in $(echo "$all_orders" | jq -c '.data.orders[]' ); do
    echo "$order"
done;
우리는 왜 사용합니까IFS=$'\n'?기본적으로 bash도 탭과 빈칸을 나누기 때문에 응답의 다양한 이름 (예를 들어 식당, 배달원) 에 빈칸이 있을 수 있습니다.
이제 데이터베이스에 저장하기만 하면 됩니다.다음 주문서를 얻기 위해 코드를 작성합니다.전반적으로 말하면 전체 대본은 이렇다.
#!/bin/bash

# Your Swiggy Session ID, check screenshot #1 
SESSION_ID="__SESSION_ID__"

while true; do
    all_orders=$(curl -sL "https://www.swiggy.com/dapi/order/all?order_id=$next_order_id" \
    -H "cookie: _session_tid=$SESSION_ID")

    IFS=$'\n'
    for order in $(echo "$all_orders" | jq -c '.data.orders[]' ); do
        # We use $$ to wrap $order because it takes cares spaces in the data
        psql "postgres://shubhamjain@localhost/stats" -c "
            INSERT INTO swiggy (order_id, data) VALUES (
               '$(echo "$order" | jq -r '.order_id')',
                \$\$$order\$\$
            );
        "
    done;

    # Next order id would be order id of the last object in array
    next_order_id=$(echo "$all_orders" | jq '.[-1].order_id')
done;
이 작업을 실행하면 다음과 같은 내용이 표시됩니다.

어느 순간 실패하기 시작할 것입니다. 이것은 스크립트가 이미 종점에 이르렀음을 의미하며, 스크립트를 종료할 수 있습니다.
주의: 이것들은 모두 이상적인 업무 방식이 아니다.나는 정확한 프로그래밍에 흥미가 없고, 단지 멋진 것들을 긁어모을 뿐이다.

6년 됐어요.


쿨!이제 데이터가 생겼습니다.질문에 대답하기 시작합시다.

문제1: 얼마나 주문했습니까?


많이!나는 내가 여러 번 주문한 것을 알고 있지만, 나는 지금까지 위에 숫자를 쓴 적이 없다.실제로 이 프로젝트를 통해 나는 내가 주문을 얼마나 했고 돈을 얼마나 썼는지 놀랐다.
SELECT COUNT(*), EXTRACT('year' FROM date(data->>'order_time')::timestamp) as year FROM swiggy GROUP BY 2;
총 주문 수량: 915

연간 및 주문 수량
얼마 썼어요?
SELECT
   SUM(CAST(data ->> 'order_total_with_tip' AS DOUBLE PRECISION)),
   EXTRACT('year' 
FROM
   DATE(data ->> 'order_time')::TIMESTAMP) 
FROM
   swiggy 
GROUP BY
   2;
총 지출액:₹1,84,329

식당과 주문 싸움
이것은 마치 큰 돈인 것 같다.적어도 그럴듯한 중고차를 한 대 사기에는 충분하다.

문제2: 주문은 어디서 합니까?


Pareto Principle 여기에 잘 적용될 것 같아요.내가 주문한 대다수의 요리는 모두 시재라는 카페이다.나는 그곳에서 주문하는 것을 좋아한다. 그곳에는 아주 좋은 간식이 있고 모든 것이 잘 포장되어 있다.
SELECT
   COUNT(*),
   data ->> 'restaurant_name' 
FROM
   swiggy 
GROUP BY
   2 
ORDER BY
   1 DESC;

식당 vs. 주문비

질문3: 언제 주문할까요?


보아하니 나는 아침과 오후에 주문한 음식이 저녁보다 많은 것 같다.이것은 사실로 설명할 수 있다. 그것은 바로 내가 저녁에 보통 배가 고프지 않고, 저녁에는 담백한 음식을 더 좋아한다는 것이다.
SELECT
   COUNT(*),
   EXTRACT('hour' 
FROM
   TO_TIMESTAMP(data ->> 'order_time', 'YYYY-MM-DD hh24:mi:ss')::TIMESTAMP) 
FROM
   swiggy 
GROUP BY
   2;

하루 중 시간 및 주문 수

질문 4. 뭘 시킬까요?


나는 큰 식사가 아니라 패스트푸드와 디저트를 주문하는 것을 더 좋아하는 것 같다.나는 절대로 디저트를 적게 먹어야 한다.
SELECT
   cuisine,
   COUNT(*) 
FROM
   (
      SELECT
         JSONB_ARRAY_ELEMENTS_TEXT(data -> 'restaurant_cuisine') AS cuisine 
      FROM
         swiggy
   )x 
GROUP BY
   1 
ORDER BY
   2 DESC;

요리와 주문 싸움

결론


여러 해 동안 나의 습관을 이해하는 것은 재미있는 연습이다.나는 이 데이터를 깊이 파고들 수 있는 많은 방법이 있지만, 지금은 여기까지다.피로를 통찰하는 것도 좋지 않다.
나는 주문이 반드시 좋지 않을 것이라고 생각하지 않지만, 그것은 매우 게으르다.제 습관의 규모를 알고 있습니다. 의식적으로 주문을 줄이는 데 도움이 될 거라는 것을 알고 있습니다.

좋은 웹페이지 즐겨찾기