Today's

길을 나서지 않으면 그 길에서 만날 수 있는 사람을 만날 수 없다

파이썬 스크립트

Threads API: 포스팅 조회·삭제 자동화 정리 (ft chatGPT)

Billcorea 2025. 8. 17. 15:26
반응형

 

Threads API: 포스팅 조회·삭제 자동화 정리

작성일: 2025-08-16 · 실행 환경: Windows 11 / Python

오늘 정리한 내용은 Threads Graph API로 내가 올린 포스팅을 조회하고, 5초 간격으로 하나씩 삭제하는 방법이야. 페이지네이션, 오류 처리(특히 rate limit)까지 한 번에 볼 수 있게 깔끔하게 묶었어.

Python · requests · pagination · deletion
스크립트 작성해 보기

 

목차

1. 준비물 2. 포스팅 목록 조회 (페이지네이션) 3. 5초 간격 삭제 4. Rate Limit & 일일 삭제 제한 5. 통합 예제 코드 (복사해서 실행) 6. 자주 겪는 에러와 해결 팁

1. 준비물

  • Threads Access Token (스코프/권한 포함). 토큰은 로컬 DB나 안전한 저장소에 보관.
  • threads-user-id 또는 me 사용. 여기선 페이지/사용자 ID를 PAGE_ID로 사용.
  • Python 모듈: requests
엔드포인트 요약
  • 목록 조회: GET /v1.0/{user-id}/threads
  • 단건 삭제: DELETE /v1.0/{post-id}

2. 포스팅 목록 조회 (페이지네이션)

Threads는 기본적으로 페이징을 쓰기 때문에, paging.next가 없어질 때까지 반복해서 호출하면 전체 목록을 모을 수 있어.

import requests

def get_all_threads(page_id: str, access_token: str, limit: int = 25):
    url = f"https://graph.threads.net/v1.0/{page_id}/threads"
    params = {
        "fields": "id,text,media_type,permalink,timestamp",
        "limit": limit,
        "access_token": access_token,
    }

    all_posts = []
    while url:
        resp = requests.get(url, params=params)
        if resp.status_code != 200:
            print("❌ 목록 조회 실패:", resp.status_code, resp.text)
            break

        data = resp.json()
        posts = data.get("data", [])
        if not posts:
            print("ℹ️ 더 이상 게시글 없음")
            break

        all_posts.extend(posts)
        print(f"➡️ 현재까지 {len(all_posts)}개 수집")

        paging = data.get("paging", {})
        url = paging.get("next")  # 다음 페이지 없으면 None
        params = None  # next는 full URL 이므로 params 제거

    print(f"📋 총 {len(all_posts)}개 게시글 불러옴")
    return all_posts
포인트
  • params = None: paging.next는 전체 URL이므로 중복 파라미터 방지.
  • NoneType 에러는 보통 응답에 data/paging가 없을 때 발생 → 딕셔너리 접근은 항상 .get()으로 안전하게.

3. 5초 간격 삭제

가져온 목록을 순회하면서 5초 간격으로 한 건씩 삭제해. 대량 작업 시 서버 보호와 한도 초과 방지에 도움이 돼.

import time
import requests

def delete_thread(post_id: str, access_token: str) -> bool:
    url = f"https://graph.threads.net/v1.0/{post_id}"
    resp = requests.delete(url, params={"access_token": access_token})
    if resp.status_code == 200:
        print(f"🗑️ 삭제 성공: {post_id}")
        return True
    else:
        print(f"❌ 삭제 실패: {post_id} | {resp.status_code} {resp.text}")
        return False

def delete_threads_with_delay(posts: list, access_token: str, delay: int = 5):
    for idx, post in enumerate(posts):
        post_id = post.get("id")
        if not post_id:
            continue

        delete_thread(post_id, access_token)

        # 마지막 아이템 전까지 대기
        if idx < len(posts) - 1:
            print(f"⏳ {delay}초 대기 후 다음 삭제")
            time.sleep(delay)

4. Rate Limit & 일일 삭제 제한

중요: 문서 기준으로 삭제는 하루(24h) 1계정당 100건 제한이 있어. 이 한도를 넘으면 Calls to this api have exceeded the rate limit 같은 오류가 발생하고, 다음날(쿨다운 후) 다시 시도해야 해.

  • 요청 간격을 늘려도 하드 제한은 초과할 수 없음.
  • 여러 날에 나눠서 100개씩 지우는 전략이 필요.

5. 통합 예제 코드 (복사해서 실행)

아래 스크립트는 전체 목록 조회 → 5초 간격 삭제까지 한 번에 수행하는 미니멀 버전이야.

import requests
import time

PAGE_ID = "YOUR_PAGE_OR_USER_ID"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"

def get_all_threads(page_id: str, access_token: str, limit: int = 25):
    url = f"https://graph.threads.net/v1.0/{page_id}/threads"
    params = {
        "fields": "id,text,media_type,permalink,timestamp",
        "limit": limit,
        "access_token": access_token,
    }
    all_posts = []
    while url:
        r = requests.get(url, params=params)
        if r.status_code != 200:
            print("❌ 목록 조회 실패:", r.status_code, r.text)
            break
        body = r.json()
        posts = body.get("data", [])
        if not posts:
            break
        all_posts.extend(posts)
        url = body.get("paging", {}).get("next")
        params = None
    return all_posts

def delete_thread(post_id: str, access_token: str) -> bool:
    url = f"https://graph.threads.net/v1.0/{post_id}"
    r = requests.delete(url, params={"access_token": access_token})
    if r.status_code == 200:
        print("🗑️ 삭제 성공:", post_id)
        return True
    else:
        print("❌ 삭제 실패:", r.status_code, r.text)
        return False

def delete_threads_with_delay(posts: list, access_token: str, delay: int = 5):
    for i, post in enumerate(posts):
        pid = post.get("id")
        if not pid:
            continue
        delete_thread(pid, access_token)
        if i < len(posts) - 1:
            print(f"⏳ {delay}초 대기")
            time.sleep(delay)

if __name__ == "__main__":
    posts = get_all_threads(PAGE_ID, ACCESS_TOKEN)
    print("총 개수:", len(posts))
    # 필요에 따라 일부만 삭제 (예: 앞 20개만)
    to_delete = posts[:20]
    delete_threads_with_delay(to_delete, ACCESS_TOKEN, delay=5)

6. 자주 겪는 에러와 해결 팁

  • 'NoneType' object is not subscriptable → 응답에 data 또는 paging이 없음. .get()로 접근하고 None 체크.
  • 429 Too Many Requests 또는 Calls to this api have exceeded the rate limit → 호출 한도 초과. 간격 늘리기 + 일일 삭제 100건 준수.
  • 토큰 만료/권한 오류 → 토큰 재발급/새 스코프 확인.
운영 팁
  • 대량 삭제는 날짜별 100개 제한 고려해서 배치로 나누기.
  • 삭제 전에는 permalink를 백업 목록으로 저장해두면 안전.

© 2025-08-16 · 작성: Threads 자동화 노트

반응형