codingeverybody / codingyahac

https://coding.yah.ac
291 stars 50 forks source link

비전공자, 파이썬(python) 크롤링을 활용한 텔레그램봇 알림 제작 문의 입니다. #701

Open minangkabau opened 5 years ago

minangkabau commented 5 years ago

해결하고자 하는 문제

최신 글과 이전 글을 비교하여 새 글이 뜨면 새 글에 대한 제목과 url을 , 새 글이 안떳으면 안떳다는 알림을 주고 싶습니다. 그런데 현재 코드에서는 분명 기존에 글과 최신 글(latest.text)가 같음에도 불구하고 새 글이 안떳다는 알림을 보내주지 않습니다. 뿐만 아니라 새 글들이 아닌 1페이지 분량의 자료들을 보내고 있습니다.. 이걸 해결하고 싶습니다. 최종 : 파이썬을 이용해서 매일 아침마다 새 글에 대한 제목과 url을 알려주는 텔레그램봇을 만드려고 합니다. 학교 홈페이지 공지사항 및 기숙사 홈페이지 공지사항 등 총 14개 사이트의 공지사항을 크롤링 받은 후 새로 올라온 공지사항 제목과 url을 텔레그램 채팅봇을 통해 알려주려고 합니다. 14개의 목록 중 사용자가 지정한 홈페이지의 새로운 공지만 알림 받도록 하는것도 구현하고 싶습니다.

코드 혹은 오류

import telegram import requests from bs4 import BeautifulSoup import json import os import time from multiprocessing import Pool # Pool import하기

python파일의 위치 BASE_DIR = os.path.dirname(os.path.abspath(__file__))

텔레그램 토큰 my_token = '제 토큰 bot = telegram.Bot(token = my_token) HTTP GET request notice = requests.get('크롤링 하려는 url) HTML 소스 가져오기 notice = notice.text HTML 소스코드를 파이썬 객체로 변환합니다. soup_notice = BeautifulSoup(notice, 'html.parser') 태그를 포함하는 요소를 추출합니다. notice_a = soup_notice.select('table > tbody > tr > td > a') latest = notice_a[0].text data = {} 아래와 같이 코드를 구성하면 latest.txt 파일에 가장 최신 글의 제목이 저장된다.

with open(os.path.join(BASE_DIR, 'latest.txt'), 'r+') as f_read: before = f_read.readline() if before != latest: for title in notice_a: notice_a가 href 속성을 가지고 있다면 if title.has_attr('href'): href 속성의 값으로 notice라는 문자가 포함되어 있다면 if title.get('href').find('notice') != -1: data[title.text] = title.get('href') with open(os.path.join(BASE_DIR, 'notice_a.json'), 'w+') as json_file: json.dump(data, json_file) while 1: bot.sendMessage(chat_id = '챗아이디', text = "{0}{1}".format(title.text,data[title.text])) if not before == latest: break else: bot.sendMessage(chat_id = '챗아이디', text = '새 글이 없어요ㅠㅠ') f_read.close()

with open(os.path.join(BASE_DIR, 'latest.txt'), 'w+') as f_write: f_write.write(latest) f_write.close()

환경

사용중인 운영체제, 언어, 라이브러리의 버전을 적어주세요.

  • 운영체제 : 윈도우 8.1
  • 언어 : 파이썬 3.7.2
  • 라이브러리 : beautifulsoup4(4.8.0), bs4(0.0.1), requests(2.22.0), telegram(0.0.1), python-telegram-bot(11.1.0),
  • 기타 : 경영학을 전공하는 비 전공자입니다. json 관련해서는 텔레그램 봇 만드는거를 구글링 하다보니까 있어서 적었는데 어떻게 활용해야 될지는 모르겠습니다.

시도해본 방법

  1. 크롤링 하기
  2. 크롤링 결과 텔레그램 전송하기
  3. 크롤링 결과 중 제목과 url 만 뽑아서 전송하기.
  4. 현재 크롤링한 최신 글과 기존에 크롤링한 자료를 비교. 동일하다면 최신 글이 없다는 메시지를, 동일하지 않다면 최신 글에서 부터 기존 글 까지의 제목과 url을 텔레그램에게 전송하기. while 1: bot.sendMessage(chat_id = '채널 아이디', text = '새 글이 올라왔어요') if not before == latest: break 그래서 이걸 넣었는데 변화없이 한 페이지 분량의 자료들을 크롤링 해서 보내줍니다. 뿐만 아니라 latest = notice_a[0].text 이 값에 '0'을 넣든 '1'을 넣든 새로운 글이 없다는 메시지가 아닌 1페이지 분량의 제목과 url을 보내줍니다.
TahoLee commented 5 years ago

코드안에 많은 if, while들리 있는데, indentation이 어떻게 되어있는지 모르겠어요. 아시겠지만, python에서는 들여쓰기에 따라서 맥락이 달라질 수 있는데, 여기서는 그런 부분을 확인할 수 없어서 뭐라 말씀드리기가 어렵네요ㅜㅜ 일단 최신인지 아닌지를 확인하는 것은 게시판에서 가져온 가장 최근의 내용에 대한 링크를 확인해서 비교하는거 같습니다. 크롤링을 해오고 있는 페이지의 구조에 따라서도 많이 달라질 수 있는데, 예를 들어서 새글이 올라오고는 있지만, 주요한 알림은 상단에 고정으로 받아오기쌔문에 변화가 있어도 눈치챌 수 없을 떄도 있어요. 그러나 지금은 매번 같은 내용이 날라온다고 하니 조건문에서 뭔가 빠진거 같아요. 다시한번 말씀드리지만, 조건문의 구조가 어떻게 되어있는지 알 수 있도로 원래 소스를 보여주시면 좋을거 같아요. 지금은 아무런 들여쓰기가 없어서 확인할 수 없습니다.