상세 컨텐츠

본문 제목

[Python] 오늘자 인벤 기사 추출하는 프로그램 with PyQt

[기록] Programming

by brightwing1218 2020. 7. 26. 13:53

본문

결과물

  • 날짜를 세팅하고, InvenCrawlStart 버튼 클릭 시, 날짜에 해당하는 기사의 이름과 링크를 반환.
  • SetToday 버튼 클릭 시, 오늘 날짜를 자동 세팅.

'

미해결 & 향후 보완할 것

  • clicked_crawlStart 메서드:
    페이지 검색 범위(1~max)를 정해 놓고, 해당 일자에 해당하는 기사가 하나라도 걸리면 그 페이지의 기사만 크롤링하는 로직이다. 따라서, 특정 일자의 기사가 여러 페이지에 걸쳐 있을 경우 제대로 추출이 안 된다 ㅋㅅㅋ
    [2020-08-30] 해당 문제 해결! 

    아울러, 페이지 검색 범위도 GUI 상에서 제어할 수 있게 해야 쓸만할 듯. 한 두 페이지가 아니라서...한 달에 무려 50페이지 정도의 기사가 생산되고 있는 듯.

  • GUI 상의 링크를 눌렀을 때 하이퍼링크를 걸어주고 싶다.

  • 표를 크게 보고 싶어서 프로그램 UI를 늘려도, 테이블이 커지지 않는다...테이블 같이 커지도록 해야 한다.

코드

from bs4 import BeautifulSoup
import requests
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
from PyQt5.QtCore import QDate
import re
form_class = uic.loadUiType("myCrawler.ui")[0] #UIClass를 만들어주는구나!

class MyWindow(QDialog, form_class): #윈도우 만들어주기 + 조작 정의
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        #[버튼] 기능 정의
        self.crawlStart.clicked.connect(self.clicked_crawlStart) #[버튼] 크롤링 시작
        self.setToday.clicked.connect(self.clicked_setToday) # [버튼] dateEdit 칸을 오늘 날짜로 변경
        #self.articleTable.clicked.connect(self.clicked_articleTable)  # [버튼] articleTable의 링크 열을 눌렀을 때, 해당 링크로 연결 (미구현)

    #def clicked_articleTable(self): # [버튼] articleTable의 링크 열을 눌렀을 때, 해당 링크로 연결 (미구현)
        #if item.column() == 1:
            #webbrowser.open('www.google.com')

    def clicked_setToday(self):
        self.dateEdit.setDate(QDate.currentDate())

    def clicked_crawlStart(self): #크롤링하고, 그 결과를 articleList에 등록해준다.
#-------------------------------------------------------------------------------------
        #날짜를 구한다.
        date = self.dateEdit.date().toString('yy-MM-dd')

#-------------------------------------------------------------------------------------
        # soup하는데, 긁을 수 있는 기사가 나오거나 정해진 페이지까지 탐색을 완료할 때까지 계속 페이지 넘긴다.
        #문제는, 하루에 업로드된 기사 전체를 알 수는 없다는 것(페이지에 걸친 거라던가...). 이건 개선 필요한 사항으로 냅두자.
        #maxSearchPage도 ui에서 컨트롤 가능하게 빼야 제 역할 할 듯
        Articles_Today = []
        searchPage = 1
        maxSearchPage = 50
        try_now = 0
        try_previous = 0

        #오늘자 아티클을 1개라도 찾았고, 다음 페이지에서 아무 것도 발견하지 못한다면.
        while searchPage <= maxSearchPage:
            soup = Crawling.getSoup(f"http://www.inven.co.kr/webzine/news/?page={searchPage}")
            Articles_Today = Crawling.InvenFilter(soup, date)
            try_now = len(Articles_Today)

            #발견된 아티클이 1개라도 존재하고, 발견된 아티클의 이전과 현재 갯수가 동일하면 멈춘다. (1페이지 넘어서까지 걸쳐 있는 경우를 커버)
            if len(Articles_Today)>0 and try_now == try_previous:
                break

            else:
                try_previous = len(Articles_Today)
                searchPage = searchPage + 1

#-------------------------------------------------------------------------------------
        #articleTable에 등록

        #articleTable의 Row 조정
        self.articleTable.setRowCount(len(Articles_Today))

        #Row를 1행씩 올려가면서 데이터 채우기
        currentRow = 0

        for article in Articles_Today: #QtableWidgetItem으로 변환
            article_name = QTableWidgetItem(article[0])
            article_link = QTableWidgetItem(article[1])

            self.articleTable.setItem(currentRow, 0,article_name)
            self.articleTable.setItem(currentRow, 1, article_link)

            currentRow += 1

class Crawling(): #크롤링 관련 함수들을 모아줌.
    def getSoup(url): #페이지 URL에 접속하여, html 코드를 받아온다.
        source = requests.get(url)
        soup = BeautifulSoup(source.text, 'html.parser')
        return soup

    #인벤에서의 오늘자 기사만 추출하기
    def InvenFilter(soup, date):
        global Articles_Today
        Articles_All = soup.find('div', class_='webzineNewsList tableType2').find_all('div', class_='content')

        for article in Articles_All:
            article_info = article.find('span', class_= 'info').getText()
            if date in article_info:
                name = article.find('a').getText()
                href = article.find('a')["href"]
                Articles_Today.append((name, href))

        return Articles_Today

#전체 뉴스에서 nnnn-nn-nn일자 기사만 긁어옴
if __name__ == "__main__":
    Articles_Today = []
    app = QApplication(sys.argv)
    myWindow = MyWindow()
    myWindow.show()
    app.exec_()

 

관련글 더보기

댓글 영역