백인감자

파이썬 웹크롤링 내용 텔레그램 메시지 전송 본문

파이썬

파이썬 웹크롤링 내용 텔레그램 메시지 전송

백인감자 2023. 7. 30. 23:07

텔레그램 메시지 전송은 이전 포스팅에서도 다뤘다.

 

어떤 내용을 텔레그램으로 받을까하다가 네이버 경제뉴스 헤드라인 목록을 전송해보려한다.

 

1.준비

 

기본적으로 필요한 pip 패키지 및 크롤링에 대한 기본 정보는 아래 블로그 참고

 

https://www.snugarchive.com/blog/python-web-scraping/

 

파이썬 웹 크롤링? 웹 스크래핑 개념과 실습 예제

Python 웹 스크래핑 코드로 실습하기

www.snugarchive.com

 

텔레그램 봇 설치 등은 아래 블로그 내용 참고

 

https://junuuu.tistory.com/492

 

업비트 RSI 알림이 만들기(with 텔레그램 봇)

개요 Python, Upbit API, Telegram API를 활용해서 업비트 RSI 알림이를 만들어 보겠습니다. 여기서 RSI란 Relative Strengh Index의 약자입니다. 상대 강도지수라고 불리는 보조지표로 0에 가까울수록 파는 힘이

junuuu.tistory.com

 

2. 대상 url 선정

 

나의 경우 네이버 글로벌경제 뉴스 메인화면으로 선택했다.

 

https://news.naver.com/main/list.naver?mode=LS2D&mid=shm&sid1=101&sid2=262 

 

네이버 뉴스

다양한 기사 정보를 제공합니다.

news.naver.com

 

 

 

 

목표 : 위 url 접속했을때 나오는 헤드라인 기사의 제목과 url 을 가져와서 텔레그램에 전송

 

 

3. 코드 작성

 

 

크롬 개발자 도구에서 내가 추출해야하는 영역의 태그를 확인한다.

 

class명이 type06_headline 인 태그의 내용을 가져와야되는것으로 보인다.

 

생각할 점 :  기사 제목, url 을  가져와야하는데 기사에 이미지가 있는 경우 a태그가 2개가 존재하여 url 중복발생

 

아래를 보자.

1번기사는 이미지가 존재하는 기사, 2번기사는 이미지가 없는 기사이다.

 

이미지가 있는 기사는 이미지를 클릭 시 , 기사제목을 클릭 시 링크 이동이 되고

 

이미지가 없는 기사는 기사제목을 클릭 시 링크 이동이 된다.

 

이미지가 있는 기사는 a태그가 2개 존재 , 이미지가 없는 기사는 a태그가 1개 존재하고있다.

 

이미지가 있는 기사중 이미지소스를 담고있는 a태그의 경우 속성값만 존재하고 a태그 자체의 텍스트값은 공백문자 한개가

들어가 있는 형태였다.

 

단순 null값이 아닌  공백문자가 들어가있었기때문에 isspace() 함수를 활용하여 url 중복을 방지했다.

 

위와 같은 조건들은 본인이 크롤링 하려는 웹사이트의 구성에 따라 다르기 때문에 잘 확인해봐야한다.

 

 

 

import requests
from bs4 import BeautifulSoup
import os
import sys
import logging
import traceback
import telegram
import asyncio

#요청 부분

url ="https://news.naver.com/main/list.naver?mode=LS2D&mid=shm&sid1=101&sid2=262"
#header 정보 경우 사용자환경마다 상이함
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}


res = requests.get(url, headers=headers)
res.raise_for_status()




# soup 객체 만들기
soup = BeautifulSoup(res.text, "lxml")
newsBox = soup.find('ul', attrs={"class": "type06_headline"}) #  ul 태그중 class 명이 type06_headline 추출
news = newsBox.find_all('a') #  'a'태그 모두 찾아 변수 news 할당

i=1
msg = ""
title= ""
# 반복문으로 제목 가져오기(터미널 창 출력)

for article in news: 
  title = article.text
  #print(title)
  link = article.get("href")
  #이미지 있는 뉴스의 경우 url 2번 나오고 있어서 중복제거
  if not title.isspace():
      msg =  msg + str(f"{str(i)}위: {title}\n{link}\n")
      i = i + 1    
  title =""

print(msg)

 

headers = {"User-Agent": "[WhatIsMyBrowser에 나타난 나의 유저 정보]"}

header 정보 경우 사용자환경마다 상이하므로 아래 링크의 결과값을 넣어주도록하자.

https://www.whatismybrowser.com/detect/what-is-my-user-agent/

 

What is my user agent?

Every request your web browser makes includes your User Agent; find out what your browser is sending and what this identifies your system as.

www.whatismybrowser.com

 

 

 

결과는 아래와 같다.

 

 

4. 텔레그램에 전송

 

텔레그램 봇에 메시지 전송을 위해서 텔레그램 라이브러리 및 코드를 추가해준다.

 

import requests
from bs4 import BeautifulSoup
import os
import sys
import logging
import traceback
import telegram
import asyncio


#지정key값 
chat_id_value = '사용자 chat_id'
token_value = '사용자 token_value'


# -----------------------------------------------------------------------------
# - Name : send_telegram_message
# - Desc : 텔레그램 메시지 전송
# - Input
#   1) chat_id : chat_id
#   2) token : token
#   3) message : 보낼 메시지
# - Output

async def send_telegram_message(chat_id_value, token_value, message):
    try:
        bot = telegram.Bot(token=token_value)
        await bot.sendMessage(chat_id=chat_id_value, text=message)
    except Exception as e:
        print(f"텔레그램 메시지 전송오류 : {e}")


async def economy_news() :

    #요청 부분

    url ="https://news.naver.com/main/list.naver?mode=LS2D&mid=shm&sid1=101&sid2=262"

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}


    res = requests.get(url, headers=headers)
    res.raise_for_status()




    # soup 객체 만들기
    soup = BeautifulSoup(res.text, "lxml")
    newsBox = soup.find('ul', attrs={"class": "type06_headline"}) #  ul 태그중 class 명이 type06_headline 추출
    news = newsBox.find_all('a') #  'a'태그 모두 찾아 변수 news 할당

    i=1
    msg = ""
    title= ""
    # 반복문으로 제목 가져오기(터미널 창 출력)

    for article in news: 
      title = article.text
      #print(title)
      link = article.get("href")
      #이미지 있는 뉴스의 경우 url 2번 나오고 있어서 중복제거
      if not title.isspace():
          msg =  msg + str(f"{str(i)}위: {title}\n{link}\n")
          i = i + 1    
      title =""

    
    await send_telegram_message(chat_id_value, token_value,msg) 

# -----------------------------------------------------------------------------
# - Name : main
# - Desc : 메인
# -----------------------------------------------------------------------------
if __name__ == '__main__':
    try:
        # 로직 시작
        asyncio.run(economy_news())
    except KeyboardInterrupt:
        logging.error("KeyboardInterrupt Exception 발생!")
        logging.error(traceback.format_exc())
        sys.exit(-100)
    except Exception:
        logging.error("Exception 발생!")
        logging.error(traceback.format_exc())
        sys.exit(-200)

 

 

5. 전송결과

 

Comments