2023. 4. 26. 01:23ㆍ프로젝트/주간책톡
앞서서
이런 형태의 dataframe 을 얻었다!
그런데 이걸 슬랙 api 를 이용해 봇으로 보내려면 어떤 방법이 있을까?
- 크롤링 한 순서대로 1. 제목[1], 2. 저자[1], 3.출판사[1] .... 이런식으로 하나씩 보내기.
- 리스트 형태로 묶어서 리스트 씩 보내기
- 표 형태로 사진으로 보내기
- 등등..
당신이 한 생각은 이미 누군가가 생각 했었다.
사업할때나 뭔가 아이템을 가지고 상업적으로 이용해보려면 화가나는 말이지만, 문제를 해결 하는 입장에서는 정말 기쁜 말이다. 뉴턴이 거인의 어깨위에 앉았기 때문에 더 멀리 볼수 있었다.말처럼. 누가 먼저 고민을 해줬다는 것이다!
물론 (대부분의) 해결방법도!
import pandas as pd
import matplotlib.pyplot as plt
import os
def dataframe_to_table(df):
fig, ax = plt.subplots(figsize=(df.shape[1]*1.5, df.shape[0]*0.5))
ax.axis("off") # 축의 테두리 숨김 (: 표를 깔끔하게)
table = ax.table(cellText=df.values, colLabels=df.columns, cellLoc="center", loc="center") # cellLoc 셀 내 텍스트 정렬
table.set_fontsize(10)
fig.tight_layout() # 요소들 간격 최적화
plt.show()
data = {
"A": [1, 2, 3],
"B": [4, 5, 6],
"C": [7, 8, 9]
}
df = pd.DataFrame(data)
dataframe_to_table(df)
위 코드를 실행하면 이런 표를 얻을수 있다!
ax.axis("off") # 축의 테두리 숨김 (: 표를 깔끔하게)
이 코드가 없다면 축의 테두리가 나타나
mapplotlib 을 주로 사용하는 목적대로 나오지만, 내가 원하는 건 깔끔한 표의 이미지이기에 축을 숨겼다.
이 이미지 파일을 전송하면 된다!
import pandas as pd
import matplotlib.pyplot as plt
import os
def dataframe_to_image(df, image_path):
fig, ax = plt.subplots(figsize=(df.shape[1]*1.5, df.shape[0]*0.5))
ax.axis("off")
table = ax.table(cellText=df.values, colLabels=df.columns, cellLoc="center", loc="center")
table.set_fontsize(10)
fig.tight_layout()
plt.savefig(image_path, dpi=300, bbox_inches="tight") # bbox_inches='tight' 이미지의 경계를 테이블 주위에 타이트하게!
plt.close() # 리소스 관리 차원에서 해제. 다음 그림 생성 할떄 이전 그림의 리소스가 중첩x, 메모리 누수 방지!
data = {
"A": [1, 2, 3],
"B": [4, 5, 6],
"C": [7, 8, 9]
}
df = pd.DataFrame(data)
# DataFrame을 이미지로 변환
image_path = "dataframe_image.png"
dataframe_to_image(df, image_path)
# Slack에 이미지 전송
api_token = "슬랙 api 토큰값"
channel = "#채널명"
message = "표 형태 보내기 연습" #이미지와 함께 말할 내용
send_slack_image(api_token, channel, image_path, message=message)
# 전송 후 이미지 파일 삭제
os.remove(image_path)
위 코드를 실행하면
텍스트와 함께 이미지의 형태로 잘 보내어 진다.
아까 뽑아내었던 books_df 를 보내면
글이 너무 작고 글이 깨진다.
표의 스케일이나 auto_set_font_size 를건드려봐도
글이 너무 길어서 ? 한글 문제? 일단 나중에 해결하도록 기록해두고,
슬랙 봇의 목적인 데이터셋 확보에는 이미지 보다는 텍스트가 접근성이 좋다. 고 자기합리화를 한뒤
그렇다면 표의 형식을 유지한 채로 텍스트의 형태로 보내주고 싶은데.. 어떻게 해야할까 찾아보았다.
import pandas as pd
import requests
def send_slack_dataframe(api_token, channel, dataframe, message=None):
url = "https://slack.com/api/chat.postMessage"
headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json"
}
# DataFrame을 텍스트 형식으로 변환
texted_dataframe = dataframe.to_string(index=False) #df 를 str 로 변환하고 index 를 생략
# 코드 블록 형식으로 감싸기
code_block = f"```\n{texted_dataframe}\n```"
'''
f : f-string 임을 나타냄. {} 포매팅을 사용하게해줌
``` ``` slack 에서 코드블록을 만들때 사용되는 마크다운 문법 <- 이놈이 포인트
\n 개행
{} 포매팅
'''
# 메시지와 함께 전송
if message:
payload = {
"channel": channel,
"text": f"{message}\n{code_block}"
}
else:
payload = {
"channel": channel,
"text": code_block
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
data = {
"A": [1, 2, 3],
"B": [4, 5, 6],
"C": [7, 8, 9]
}
df = pd.DataFrame(data)
# Slack에 DataFrame 전송
api_token = "api 토큰"
channel = "#채널명"
message = "이미지 말고 코드블록 형태로 보내기연습" #이미지와 함께 말할 내용
send_slack_dataframe(api_token, channel, df, message=message)
괜찮은것 같기도하나 글이 길어진다면?
생각보다 보기 좋게 나왔다. 데이터 셋으로는 괜찮아 보인다.
하지만 시각적으로 좀 정렬이 됬으면 좋겠는데..
그 답은 tabulate 패키지.
나중에 tablutate 에 대해서 정리하기로 하고, 한줄요약 하자면
tabulate : Python에서 테이블 형식의 데이터를 깔끔하게 출력하기 위한 도구
import pandas as pd
import requests
from tabulate import tabulate
def send_slack_dataframe_with_grid(api_token, channel, dataframe, message=None):
url = "https://slack.com/api/chat.postMessage"
headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json"
}
# DataFrame을 격자가 있는 텍스트 형식의 표로 변환
texted_dataframe = tabulate(
dataframe, # 바꿀 객체
headers='keys', # 테이블의 헤더로 열 이름을 사용, keys 는 기본값
tablefmt='grid', # 테이블의 출력 형식
showindex=True # DF의 인덱스를 테이블 왼쪽에 출력, 숨기려면 false
)
# 코드 블록 형식으로 감싸기
code_block = f"```\n{texted_dataframe}\n```"
# 메시지와 함께 전송
if message:
payload = {
"channel": channel,
"text": f"{message}\n{code_block}"
}
else:
payload = {
"channel": channel,
"text": code_block
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
df = pd.DataFrame(books_df)
# Slack에 격자가 있는 표 형식의 DataFrame 전송
api_token = "api 토큰"
channel = "#채널명"
message = "tabulate 를 이용한 표형식 보내기 연습"
send_slack_dataframe_with_grid(api_token, channel, df, message=message)
괜찮게 정리가 되었다.
다음 목표는
link 로 들어가서 요약내용 크롤링해서 정리 (요약된 글의 양이 오디오는 약 20~30분 정도 의 내용),
슬랙 봇에 올렸던 것을 역으로 다시 크롤링해 데이터셋으로 만드는 것이 목표!
'프로젝트 > 주간책톡' 카테고리의 다른 글
주간책톡(부산 도서관) 크롤링 -6 카카오톡 메세지 크롤링, pygetwindow, pyautogui (2) | 2023.05.01 |
---|---|
주간책톡(부산 도서관) 크롤링 -5 페이지를 순회하며 크롤링 (0) | 2023.04.27 |
주간책톡(부산 도서관) 크롤링 -3 책 정보를 dataframe화 (pandas) (0) | 2023.04.25 |
주간책톡(부산 도서관) 크롤링 -2 XPath, CSS_SELECTOR (0) | 2023.04.24 |
주간책톡(부산 도서관) 크롤링 -1 CSS 선택자 (0) | 2023.04.24 |