본문 바로가기
사이드 프로젝트/뉴스구독 웹서비스

AWS What's new 뉴스레터3 | 크롤링데이터를 이메일로 전송하기

by 카프리썬 2021. 4. 18.
728x90

어제는 이메일로 전송할 수 있는지만 테스트해봤다. 이젠 이를 바탕으로 내 데이터를 보낼 것이다.

 

 

내 '데이터'는 먼저 코드상에서 dict list형식으로 만들어져있다.

그래서 그대로 메일을 보내보면 이렇게 된다.

 

하지만 우리는 조금더 이쁘게 보기좋게 만들어야한다. 만약 title만 보낸다면?

즉 메일에 들어갈 html body에 단순히 title 내용을 넣은것이다. 

 

결국 관건은 메일에 보낼 body를 어떻게 구성할 것인가!! 이다.

혹시 테이블처럼 한번 보내면 그래도 시각적이고 깔끔하지 않을까? 해서 dataframe형태로 변경해보았다.

<python dict to dataframe 방법>

import pandas as pd

df = pd.DataFrame(document_list)

그리고 메일에 보낼 html형식으로 다시 바꾸었다.

이때 link를 클릭할 수 있는 링크형식으로 바꾸기 위해서 escape 옵션을 주었다. 

 

<python dataframe to html 방법>

content= dataframe.to_html(escape=False)

 

하지만 여전히 마음에 들지 않는다....혹시 dataframe을 예쁜 테이블형식으로 바꾸는게 없을까 싶었다..

pretty_html_table 패키지를 검색해서 알게 되었다. 

결국 이렇게 시도해봤지만,, link연결도 되지 않고,,그렇게 예쁜편도 아니라서 패스..

더보기

<pretty_html_table 사용>

from pretty_html_table import build_table

output=build_table(dataframe,'orange_dark')

 

아, 그리고 전체 내용이 아니라 날짜를 필터링했다. 

현재날짜(오늘)와 비교해서 일주일치씩만 가져올수 있도록 수정했다.

<출처 : 날짜비교하는 방법>

published = str(feed.entries[i].published).replace("+0000","")
published_date = datetime.datetime.strptime(published,'%a, %d %b %Y %H:%M:%S ')
now_date=datetime.datetime.now()
diffday = (now_date-published_date).days #메일전송일자 기준 일주일치만

if diffday <=7:

 

결국 그냥 내가 html을 만들기로 했다..매우 귀찮고 번거롭고 은근히 짜증나는일이 아닐수 없다..

그리고 화사함(?)을 위해 이모지도 넣어봤다. 

<출처 : html에  이모지 넣는 방법>

아래의 사이트에서 코드를 복사해서 넣으면 된다.

 

일단 목표하던거는 다 끝냈지만, 뭔가 카테고리별로 구분해서 보여주던가

좀더 가독성있게? 그리고 정보를 줄 수 있게? 이 메일만 보고도 어떤 소식이 있구나를

한눈에 알 수 있도록 조금 변경해야할 것 같다. (별것도 아닌거에 욕심..이 생긴다랄까..) 

 

이제 앞으로 할일은 

1. 예쁘게 만들기 (메일 html 기획)

2. 카테고리별 구분하기

3. 구독한 카테고리에 대해서만 메일 대량전송하기 (구독자 엑셀 받기)

4. 스케쥴링 (월요일마다 전송, 일주일내용만 전송 필터링하기)


 

+4.19 메일html 디테일(날짜추가)

메일제목에 몇월몇주차 이런식이였으면 좋겠다. 매주 메일을 보낼것이기 떄문이다.

그래서 조금 구글링을 해서 찾았다. datetime과 string때문에 조금 뻘짓을 했지만..

덕분에 오늘날짜 기준으로 몇주차인지 계산하고, 이를 메일 제목으로 변경했다.

def get_week_no():
    target=datetime.now() #datetime
    firstday = target.replace(day=1)
    if firstday.weekday() == 6:
        origin = firstday
    elif firstday.weekday() < 3:
        origin = firstday - timedelta(days=firstday.weekday() + 1)
    else:
        origin = firstday + timedelta(days=6-firstday.weekday())
    return (target - origin).days // 7 + 1
    
message['Subject'] = "["+month+"월 "+str(get_week_no())+"주차] AWS What's New 소식"

 

+04.20 카테고리별 구분하기 추가

메일 html을 예쁘게 만들기를 하면서 카테고리를 구분한 내용을 추가했다.

일단은 index에 있는 내용들을 파싱해서 service관련 소식인지, 마케팅인지 구분하게 json형식을 다시 구성했다..

 

크롤링한 데이터의 카테고리를 분류하는 classify 함수코드 보기 ▼

더보기

매개변수로 받는 term는 원래 index에 풀로 붙어 있었던 string이다.

general:products/amazon-athena,general:products/aws-lambda,marketing:marchitecture/analytics 이런거

우선 분류를 마케팅인지, product인지만 구분해서 아마 추가로 구분기준을 추가해야할 것 같다 

def classify(term):
    index_documnet ={}
    service_list =[]
    marketing_list=[]
    try:
        category_list = term.split(",")
        for category in category_list:
            if "general" in category:
                service_list.append(category.split("general:products/")[1])
                index_documnet['service'] = service_list
            elif "marketing" in category:
                marketing_list.append(category.split("marketing:marchitecture/")[1])
                index_documnet['marketing'] = marketing_list
            else:
                index_documnet['else']=category
    except:
        index_documnet = {}
    return index_documnet
    
    
    
 def crawling_aws(url,trans):
  ..생략 ..
  
 if diffday <=7:
 	kor_title= trans.translate(feed.entries[i].title,src="en",dest="ko")
	..생략..
    
    if feed.entries[i].tags:
    tags_list = feed.entries[i].tags
    term = tags_list[0]['term']

    else:
    term = "null"

    sub_index = classify(term)

    aws_document['date'] = published_date.strftime("%Y.%m.%d")
    aws_document['index'] = sub_index

    
    
    

그래서 mongoDB안에서 Index값을 보면 (mongoDB명령어)

db.aws.find({},{"_id":false,"index":true,"title":true}).pretty()

이렇게 서브 json형식으로 추가로 구분해서 넣었다.

그리고 메일을 보낼때 html에서 가져오도록 했다. 그래서 어쩌다 메일form인 html이 조금 더러워졌지만..

 

더러운 html 만들기 inline코드 보기 ▼

더보기
def create_html(document_list):
    html =''
    html += '<!DOCTYPE html> ' \
            '<html>' \
            '<body>' \
            '<h2 style="font-family:Sans-Serif;text-align:center"><strong>AWS Weekly Whats New &#127752;</strong</h2>' \
            '<hr style="border:0;border-top:solid 1px #e2e2e2;width:90%;margin:20px auto" class="horizontal-line">'
    for content in document_list:
        html+='<div style="margin-top:20px">' \
              '<h5 style="font-family:Sans-Serif;text-align:left;width:90%;margin:20px auto">'+"["+content['date']+"] "
        if 'service' in content['index']:
            for service in content['index']['service']:
                html+="#"+service
        elif 'marketing' in content['index']:
            html+="#marketing"
        else:
            html+="#else"

        html+='<br>'+content['ko_title'] +\
                  '<a href="'+content['link']+'"style="color:#FF9900;text-decoration: none;"> 더보기</a></h5>'\
                  '</div></body></html>'
    send_email(html)
    print("메일body : html형식")

 

 

결과적으로 메일 최종 형식은 이렇다!

근데 조금 욕심을 내자면, 두가지를 수정하고 싶다.

첫번째, 날짜별로 정렬 되게만들기

두번쨰, 마케팅인지, product인지 아예 구분해서 html 뿌려주기

지금은 그냥 한번에 다 나오는데 뭔가 정보를 골라내기에 번거로움이 조금 있다.

그래서 아예 화면을 나누었으면 더 가독성이 높아질 것 같다. 

그리고 이렇게 나누면 굳이 구독자 엑셀을 안만들어도 될 것 같다. 오히려 구독자 엑셀을 가지고 원하는 서비스, 원하는 정보만 선택했을때 업데이트 된 내용이 없을 수도 있을것 같아서. 대량메일전송에는 취향서비스는 넣지 말아야겠다.

 

 

이제 앞으로 할일은 

1. 예쁘게 만들기 (메일 html 기획)

2. 카테고리별 구분하기

3. 구독한 카테고리에 대해서만 메일 대량전송하기 (구독자 엑셀 받기)

4. 스케쥴링 (월요일마다 전송, 일주일내용만 전송 필터링하기)

 

그러니까 3번 패스하고 이제 스케쥴링만 걸어두면 된다!

반응형