지금까지 배운 것을 응용해서 만들어보는 미니프로젝트를 진행함

 

기획의도 : 파이썬 모듈을 활용해 데이터를 수집하고 분류하는 시스템 개발
기능  : 1. 사용자 입력 데이터 처리
         2. 입력값을 통해 이미지 검색 후 경로 추출 및 출력
         3. 추출한 이미지 경로를 통해 이미지 다운로드
         4. 입력값을 통해 뉴스 검색후 제목 추출 및 출력
         5. 추출한 제목을 하나의 문자열로 만들어 wordcloud 생성

 

============================================================================

1. 사용자 입력 데이터 처리

메인에서 실행되며 검색어, 검색기간의 시작지점과 끝지점 그리고 이미지 검색을 할지 뉴스검색을 할지 

사용자의 선택을 입력받아 입력값을 전달하며 해당하는 함수를 실행한다.

 

# 사용자의 입력과 선택을 받는 함수
def mini():
    # input 받는 부분
    search_word = input("어떤 검색어를 입력할까요? : ")
    start_date, end_date = input("기간을 설정해주세요(yyyymmdd~yyyymmdd): ").split('~')
    choose = int(input("1.이미지검색, 2.텍스트검색 (숫자를 골라주세요): "))

    # 사용자의 선택에 따라 실행되는 함수
    if choose == 1:
        search_image(search_word, start_date, end_date)
    if choose == 2:
        search_text(search_word, start_date, end_date)

 

============================================================================

2-1. 전달받은 사용자의 입력값을 이용해 이미지를 검색하고 경로를 추출하고 출력한다.

2-2. 추출된 이미지의 경로를 전달하며 이미지를 저장하는 함수를 실행한다.

 

# 입력을 전달받아 이미지를 검색하는 함수
def search_image(search_word, start_date, end_date):
    binary = 'C:\\chromedrive\\chromedriver.exe'
    browser = webdriver.Chrome(binary)
    url = "https://search.naver.com/search.naver?where=image&sm=tab_jum&query={0}&nso=p%3Afrom{1}to{2}" \
        .format(search_word, start_date, end_date)
    browser.get(url)

    # 무한 스크롤
    prev_height = browser.execute_script("return document.body.scrollHeight")

    while True:
        # 스크롤을 화면 가장 아래로 내린다
        browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
        time.sleep(3)

        curr_height = browser.execute_script("return document.body.scrollHeight")

        if (curr_height == prev_height):
            break
        else:
            prev_height = curr_height

    time.sleep(3)

    # 소스코드 다운 & 원하는 값 추출
    html = browser.page_source
    soup = BeautifulSoup(html, "lxml")
    img_list = soup.find_all("img", class_="_image _listImage")

    # 출력
    s_date = datetime.datetime.strptime(start_date, '%Y%m%d').date()
    e_date = datetime.datetime.strptime(end_date, '%Y%m%d').date()
    params = []

    for idx, val in enumerate(img_list):
        if val.get("data-lazy-src") is not None:
            params.append(val.get("data-lazy-src"))
            print('{}번째 이미지 주소 : {}'.format(idx + 1, val.get("data-lazy-src")))
        else:
            params.append(val.get("src"))
            print('{}번째 이미지 주소 : {}'.format(idx + 1, val.get("src")))

    print('\n{}부터 {} 사이에 {}은(는) {}개이고 내용은 위와 같습니다.'.format(s_date, e_date, search_word, len(img_list)))

    # 이미지 다운로드
    download_image(params, search_word)

 

============================================================================

3. 전달받은 이미지 경로를 이용해 컴퓨터에 이미지를 저장한다.

 

def download_image(params, search_word):
    for idx, p in enumerate(params, 1):
        # 다운받을 폴더 경로 입력
        urllib.request.urlretrieve(p, "C:\\image\\{}_{}.jpg".format(search_word, str(idx)))

        if idx == 50:
            break

 

============================================================================

4-1. 전달받은 사용자의 입력값을 이용해 뉴스검색을 실행하고 기사의 제목을 저장하고 출력한다.

4-2. 저장한 기사의 제목을 하나의 문자열로 만들어 wordcloud를 생성한다.

 

# 입력을 전달받아 뉴스를 검색하는 함수
def search_text(search_word, start_date, end_date):
    list_title = []
    idx = 1  # url 페이지 넘기기 위한 인덱스
    parse_word = urllib.parse.quote(search_word)  # 한글인식이 안되서 url 파싱

    # 소스코드 다운 & 원하는 값 추출 반복
    while True:
        url_str = 'https://search.naver.com/search.naver?where=news&sm=tab_pge&query={0}&sort=0&' \
                  'photo=0&field=0&pd=3&ds={1}&de={2}&cluster_rank=46&mynews=0&office_type=0&' \
                  'office_section_code=0&news_office_checked=&nso=so:r,p:from20200101to20200201,a:all&' \
                  'start={3}'.format(parse_word, start_date, end_date, idx)
        url = urllib.request.Request(url_str)
        result = urllib.request.urlopen(url).read().decode('utf-8')
        soup = BeautifulSoup(result, "html.parser")
        title = soup.find_all("a", class_="news_tit")

        for val in title:
            list_title.append(val["title"])

        # 반복 여부 체크
        check = soup.find("a", class_="btn_next")

        if check["aria-disabled"] == "true":
            break
        else:
            idx += 10

    # 출력
    s_date = datetime.datetime.strptime(start_date, '%Y%m%d').date()
    e_date = datetime.datetime.strptime(end_date, '%Y%m%d').date()
    title_str = ""

    for idx, val in enumerate(list_title):
        title_str += val + " "
        print('{}번째 기사 제목 : {}'.format(idx + 1, val))

    print('\n{}부터 {} 사이에 {}은(는) {}개이고 내용은 위와 같습니다.'.format(s_date, e_date, search_word, len(list_title)))

    # 워드클라우드로 출력
    wordcloud = WordCloud(max_font_size=200, font_path='/content/drive/My Drive/Colab Notebooks/malgun.ttf',
                          background_color='white',
                          width=1200, height=800).generate(title_str)
    plt.figure(figsize=(10, 6))
    plt.imshow(wordcloud)
    plt.axis('off')
    plt.show()

 

============================================================================

다른 조의 발표를 보고 기간 입력받을 때 예외처리 같은 것을 우리도 구현했으면 좋았겠다 하는 아쉬운 점

우리 조도 뉴스검색시 페이징처리 찾아가는 부분은 꽤나 괜찮은 것 같다.

+ Recent posts