blog:facebook_api_get_posting_2_python

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
blog:facebook_api_get_posting_2_python [2020/02/29 06:16] – ↷ Links adapted because of a move operation prgramblog:facebook_api_get_posting_2_python [2025/07/07 14:12] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Facebook API 포스팅 가져오기 #2 python으로 정리 ====== ====== Facebook API 포스팅 가져오기 #2 python으로 정리 ======
- 
 {{tag>blogs 페이스북API Facebook API 자동화 Python}} {{tag>blogs 페이스북API Facebook API 자동화 Python}}
- 
 {{section>blog:facebook_api_get_posting_1_api#intro &noindent&nolink&nouser&noeditbtn&nocomments&notags&nodate}} {{section>blog:facebook_api_get_posting_1_api#intro &noindent&nolink&nouser&noeditbtn&nocomments&notags&nodate}}
- 
  
 ===== Why Python? ===== ===== Why Python? =====
Line 12: Line 9:
   - 오프라인에도 자료를 저장하고 싶음   - 오프라인에도 자료를 저장하고 싶음
   - 데이터 정리나 라이브러리 사용이 용이함. 익숙하기 때문에 개발 시간이 단축   - 데이터 정리나 라이브러리 사용이 용이함. 익숙하기 때문에 개발 시간이 단축
-이라는 이유 때문에 데스크톱에서 주기적으로 실행시켜줘야 하지만, Python을 이용하기로 하고,\\+이라는 이유 때문에 데스크톱에서 주기적으로 실행시켜줘야 하지만, Python을 이용하기로 하고,
 PHP는 최신 현황만 불러오는 간단한 스크립트를 작성하기로 했다. PHP는 최신 현황만 불러오는 간단한 스크립트를 작성하기로 했다.
  
Line 32: Line 29:
 ==== API 호출 ==== ==== API 호출 ====
  
-[[blog:facebook_api_get_posting_1_api|1편(API 사용하기)]] 에서 받아온 cURL 과 액세스 토큰을 통해서 데이터를 받아온다.\\+[[blog:facebook_api_get_posting_1_api|1편(API 사용하기)]] 에서 받아온 cURL 과 액세스 토큰을 통해서 데이터를 받아온다.
 requests 라이브러리의 get 함수를 사용해서 데이터를 받아서 json을 dict 형식으로 변환한다. requests 라이브러리의 get 함수를 사용해서 데이터를 받아서 json을 dict 형식으로 변환한다.
  
-(Line 1의 utils 는 nested_json, get_images, UTCtoKST 등 아래에서 설명할 함수들이 포함된 파일) \\+(Line 1의 utils 는 nested_json, get_images, UTCtoKST 등 아래에서 설명할 함수들이 포함된 파일) 
 <code python; highlight: [1,11,22] > <code python; highlight: [1,11,22] >
 from utils import * from utils import *
Line 53: Line 50:
 </code> </code>
  
-\\ + 
-\\+
  
  
Line 61: Line 58:
 ==== 다음페이지 호출 ==== ==== 다음페이지 호출 ====
  
-[[#json을_DataFrame으로|json구조-다음section]]는 1-depth 에서 data와 paging 으로 구분되어 있고, paging > next 에 다음페이지 URL이 있기 때문에 존재하면 계속 받아오도록 한다.\\+[[#json을_DataFrame으로|json구조-다음section]]는 1-depth 에서 data와 paging 으로 구분되어 있고, paging > next 에 다음페이지 URL이 있기 때문에 존재하면 계속 받아오도록 한다.
  
 <code python; highlight:[5]> <code python; highlight:[5]>
Line 79: Line 76:
 output.to_excel('facebook.xlsx') output.to_excel('facebook.xlsx')
 </code> </code>
-\\ + 
-\\+
 ==== json을 DataFrame으로 ==== ==== json을 DataFrame으로 ====
-우선 Archiving과 추후 페이스북 포스팅 효과 분석 등을 위해서 눈으로 볼 수 있는 DataFrame 형식으로 변환을 하고 싶었다.\\+우선 Archiving과 추후 페이스북 포스팅 효과 분석 등을 위해서 눈으로 볼 수 있는 DataFrame 형식으로 변환을 하고 싶었다.
 하지만 받아오는 json이 아래와 같이 attachments 가 다시 dict 구조로 되어 있기 때문에 일반적인 방법으로는 DataFrame 형식으로 바꾸기 어려워 보였다. 하지만 받아오는 json이 아래와 같이 attachments 가 다시 dict 구조로 되어 있기 때문에 일반적인 방법으로는 DataFrame 형식으로 바꾸기 어려워 보였다.
  
Line 104: Line 101:
 )} )}
 </code> </code>
-\\ + 
-\\+
 그래서 recursion을 이용해서 nested json 형식을 DataFrame으로 바꿀 수 있도록 11번 라인의 nested_json 함수를 다음과 같이 만들어 보았다. 그래서 recursion을 이용해서 nested json 형식을 DataFrame으로 바꿀 수 있도록 11번 라인의 nested_json 함수를 다음과 같이 만들어 보았다.
 <code python> <code python>
Line 123: Line 120:
     return df_out     return df_out
 </code> </code>
-\\ + 
-nested_json 에서 데이터의 리스트 element 하나(DataFrame에서 한 행이 될 부분)에 대해서 nested_json_row 를 실행해서 DataFrame을 만들게 된다.\\ +nested_json 에서 데이터의 리스트 element 하나(DataFrame에서 한 행이 될 부분)에 대해서 nested_json_row 를 실행해서 DataFrame을 만들게 된다. 
-\\ + 
-nested_json_row 에서는 아래와 같이 dict나 list가 아닌 '값'이 나올 때까지 recursion을 이용해서 column명-값 을 가져오도록 했다.\\+nested_json_row 에서는 아래와 같이 dict나 list가 아닌 '값'이 나올 때까지 recursion을 이용해서 column명-값 을 가져오도록 했다.
 dict일 때는 dict의 값을 컬럼명으로, list일 때는 index를 컬럼명에 추가해서 구분이 가능하도록 하였다. dict일 때는 dict의 값을 컬럼명으로, list일 때는 index를 컬럼명에 추가해서 구분이 가능하도록 하였다.
-\\ + 
-\\+
 <code python; highlight: [5-6,10-11]> <code python; highlight: [5-6,10-11]>
 def nested_json_row(dict_data): def nested_json_row(dict_data):
Line 147: Line 144:
     return out     return out
 </code> </code>
-\\ + 
-\\+
 엑셀로 저장해서 보면, 컬럼명이 다음과 같이 잘 들어간 것을 볼 수 있다. 엑셀로 저장해서 보면, 컬럼명이 다음과 같이 잘 들어간 것을 볼 수 있다.
  
Line 154: Line 151:
  
  
-\\+
 ===== wiki문법으로 변환 ===== ===== wiki문법으로 변환 =====
-데이터들을 사용가능하도록 정리하고, 업로드가 가능한 형태로 수정하는 부분.\\ +데이터들을 사용가능하도록 정리하고, 업로드가 가능한 형태로 수정하는 부분. 
-본 사이트는 [[https://www.dokuwiki.org/dokuwiki|dokuwiki]] 를 사용하여 만들었기 때문에, 이 테이블을 wiki 문법으로 바꾸어줘야 했다.\\ +본 사이트는 [[https://www.dokuwiki.org/dokuwiki|dokuwiki]] 를 사용하여 만들었기 때문에, 이 테이블을 wiki 문법으로 바꾸어줘야 했다. 
-\\ + 
-아래 코드에서 wiki 문법을 HTML 이나 Markdown 문법 등으로 수정해서 사용하면 다른 곳에서도 사용할 수 있을 것이다. \\ +아래 코드에서 wiki 문법을 HTML 이나 Markdown 문법 등으로 수정해서 사용하면 다른 곳에서도 사용할 수 있을 것이다.  
-\\+
  
 ==== 기본정보 처리 ==== ==== 기본정보 처리 ====
Line 195: Line 192:
   * type : 포스팅 종류 (link, picutre, video 등)   * type : 포스팅 종류 (link, picutre, video 등)
  
-\\ + 
-\\+
 ==== Image 처리 ==== ==== Image 처리 ====
  
-API를 통해서 정보는 original URL이 아닌, Facebook CDN 서버를 통하는 URL로 제공.\\+API를 통해서 정보는 original URL이 아닌, Facebook CDN 서버를 통하는 URL로 제공.
 이 이미지 URL은 다음의 두 가지 경우가 존재한다. 이 이미지 URL은 다음의 두 가지 경우가 존재한다.
   - Facebook 내부 이미지(line3) : ''https://scontent.xx.fbcdn.net'' 형식은 바로 접근이 가능하기 때문에 URL을 그대로 사용.   - Facebook 내부 이미지(line3) : ''https://scontent.xx.fbcdn.net'' 형식은 바로 접근이 가능하기 때문에 URL을 그대로 사용.
   - 외부 이미지(line6~) : ''https://external.xx.fbcdn.net/safe_image.php'' 의 ''&url='' 부분이 외부 이미지 URL.   - 외부 이미지(line6~) : ''https://external.xx.fbcdn.net/safe_image.php'' 의 ''&url='' 부분이 외부 이미지 URL.
 여기에 몇가지 예외 처리를 추가하여 다음과 같이 이미지 URL 을 추출하였다. 여기에 몇가지 예외 처리를 추가하여 다음과 같이 이미지 URL 을 추출하였다.
-\\+
 <code python> <code python>
     # image 처리 ################     # image 처리 ################
Line 221: Line 218:
 </code> </code>
  
-\\ + 
-그리고 아래와 같이 ''get_images 함수'' ([[blog:facebook_api_get_posting_3_image_ftp_write|다음편(이미지 및 FTP)]]에서 설명)를 호출하여\\+그리고 아래와 같이 ''get_images 함수'' ([[blog:facebook_api_get_posting_3_image_ftp_write|다음편(이미지 및 FTP)]]에서 설명)를 호출하여
 Archiving을 위한, Archiving을 위한,
  - 이미지를 다운로드  - 이미지를 다운로드
Line 233: Line 230:
         con['picture'] = "{{blogs_facebook_upload:" + row['id']+ ".png?100}}"         con['picture'] = "{{blogs_facebook_upload:" + row['id']+ ".png?100}}"
 </code> </code>
-\\ + 
-\\+
  
 ==== 기타 처리 ==== ==== 기타 처리 ====
   * 포스팅의 대표 링크는 페이스북에서 보이는 것처럼 도메인 이름만 추출하도록 하고,   * 포스팅의 대표 링크는 페이스북에서 보이는 것처럼 도메인 이름만 추출하도록 하고,
   * message 내에 있는 링크가 길이가 길 때는 말 줄임표로 줄이도록 하고.   * message 내에 있는 링크가 길이가 길 때는 말 줄임표로 줄이도록 하고.
-  * 또한 참고로 dokuwiki문법 적용시 개행을 의미하는 '\\'가 f-string에서는 적용되지 않기 때문에 따로 처리하였다.+  * 또한 참고로 dokuwiki문법 적용시 개행을 의미하는 ''가 f-string에서는 적용되지 않기 때문에 따로 처리하였다.
 <code python> <code python>
     con['link'] = "[[" + row['attachments_data_0_unshimmed_url'] + "|"+ row['attachments_data_0_unshimmed_url'].replace("https://","").replace("http://","").split("/")[0] + "]]"     con['link'] = "[[" + row['attachments_data_0_unshimmed_url'] + "|"+ row['attachments_data_0_unshimmed_url'].replace("https://","").replace("http://","").split("/")[0] + "]]"
Line 249: Line 246:
             con['message'] = con['message'].replace(urlf, f"[[{urlf}|{urlf[:30]}...]]")             con['message'] = con['message'].replace(urlf, f"[[{urlf}|{urlf[:30]}...]]")
  
-    con['message'] = con['message'].replace('\n',\\\\ '  # SyntaxError: f-string expression part cannot include a backslash+    con['message'] = con['message'].replace('\n', '  # SyntaxError: f-string expression part cannot include a backslash
 </code> </code>
  
-\\ + 
-\\+
  
 ==== 날짜 처리 및 Template 완성 ==== ==== 날짜 처리 및 Template 완성 ====
  
-API를 통해서 제공하는 날짜 정보는 모두 [[https://ko.wikipedia.org/wiki/%ED%98%91%EC%A0%95_%EC%84%B8%EA%B3%84%EC%8B%9C|UTC]] 기준으로 되어 있다.\\ +API를 통해서 제공하는 날짜 정보는 모두 [[https://ko.wikipedia.org/wiki/%ED%98%91%EC%A0%95_%EC%84%B8%EA%B3%84%EC%8B%9C|UTC]] 기준으로 되어 있다. 
-한국은 UTC+9 시간이기 때문에 아래와 같이 timezone 라이브러리를 이용하여 변환해주는 작업이 필요하다.\\+한국은 UTC+9 시간이기 때문에 아래와 같이 timezone 라이브러리를 이용하여 변환해주는 작업이 필요하다.
  
 <code python> <code python>
Line 270: Line 267:
 </code> </code>
  
-\\+
 지금까지 작업을 바탕으로 아래처럼 각 포스팅별로 wiki문법을 적용한 Template을 만들었다. 지금까지 작업을 바탕으로 아래처럼 각 포스팅별로 wiki문법을 적용한 Template을 만들었다.
-\\+
 <code python> <code python>
     content = f"""     content = f"""
 === {con['title']} === === {con['title']} ===
- | {con['type'].upper()} | {UTCtoKST(row['created_time'])} | {con['url']} | \\\\ + | {con['type'].upper()} | {UTCtoKST(row['created_time'])} | {con['url']} |  
-\\\\+
 {con['message']} {con['message']}
 > <wrap group> > <wrap group>
Line 284: Line 281:
 </wrap> </wrap>
 <wrap column> <wrap column>
-{con['desc']} \\\\+{con['desc']} 
 {con['link']} {con['link']}
 </wrap> </wrap>
Line 294: Line 291:
 # END of for ################################## # END of for ##################################
 </code> </code>
-\\ + 
-\\+
 지금까지 for loop 를 통해서 각 포스팅 들을 만들었고, 아래처럼 Header와 Footer 를 추가하고, txt 파일로 저장하기까지 완성 지금까지 for loop 를 통해서 각 포스팅 들을 만들었고, 아래처럼 Header와 Footer 를 추가하고, txt 파일로 저장하기까지 완성
-\\+
 <code python; highlight: [1]> <code python; highlight: [1]>
 iframe = "{{url>fb_newest.php?date="+max(output['created_time']).replace('+','%2B')+"&format=m/d%20H&front=[최신:%20&mid=%EC%8B%9C%EA%B9%8C%EC%A7%80%20&end=%20%ED%8F%AC%EC%8A%A4%ED%8C%85%EC%9D%B4%20%EB%8D%94%20%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4]&style=font-size:11pt;font-color:%23333333;font-family:Helvetica,Arial,sans-serif; 100%,30 noscroll noborder left|no iframe error}}" iframe = "{{url>fb_newest.php?date="+max(output['created_time']).replace('+','%2B')+"&format=m/d%20H&front=[최신:%20&mid=%EC%8B%9C%EA%B9%8C%EC%A7%80%20&end=%20%ED%8F%AC%EC%8A%A4%ED%8C%85%EC%9D%B4%20%EB%8D%94%20%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4]&style=font-size:11pt;font-color:%23333333;font-family:Helvetica,Arial,sans-serif; 100%,30 noscroll noborder left|no iframe error}}"
Line 321: Line 318:
 f.close() f.close()
 </code> </code>
-\\ + 
-\\+
  
 ===== 추후 작업 / 다음 편 ===== ===== 추후 작업 / 다음 편 =====
Line 331: Line 328:
   - txt파일로 저장한 글로 웹 상의 문서 생성/수정   - txt파일로 저장한 글로 웹 상의 문서 생성/수정
 을 설명하도록 하겠다. 을 설명하도록 하겠다.
-\\ + 
-\\+
 또한, [[blog:facebook_api_get_posting_4_php|4편(PHP최신현황)]]에서는, 바로 위 코드의 Line 1에서 ifram으로 가져오는 PHP 페이지에 대한 설명을 해보도록 하겠다. 또한, [[blog:facebook_api_get_posting_4_php|4편(PHP최신현황)]]에서는, 바로 위 코드의 Line 1에서 ifram으로 가져오는 PHP 페이지에 대한 설명을 해보도록 하겠다.
  
-\\ + 
-\\+
  
  
  • blog/facebook_api_get_posting_2_python.1582956998.txt.gz
  • Last modified: 2025/07/07 14:12
  • (external edit)