파이썬 강좌(초급)/(실습) 크롤링

(실습)파이썬 네이버에서 강아지로 검색 후 강아지 이미지를 자동으로 크롤링 하는 프로그램 만들기 - 12.셀레니움을 이용해서 페이지 내리기

파기차차 2024. 3. 3. 13:56
728x90
반응형
SMALL

ㅁ 개요

 

O 프로그램 소개

 

 

 - 이번 글은 이전글((실습)파이썬 네이버에서 강아지로 검색 후 강아지 이미지를 자동으로 크롤링 하는 프로그램 만들기 - 11.이미지 저장을 위한 별도 폴더 생성)에 이은 13번째 마지막 글로 많은 수의 이미지(예: 강아지 100장 등)를 내려 받으려면 셀레니움을 이용하여 동적으로 페이지 다운 후 다운로드 해야 하는데, 이러한 동적 페이지 다운 방법에 대해 알아 보겠습니다.

 

 

O 완성된 프로그램 실행 화면

 

 

 - 최종 완성된 프로그램의 결과화면은 아래와 같습니다.

 

 

1.이전 소스코드( 11.crawing_naver.py )에서 다운로드할 이미지 수를 50개로 지정(j=50)하고 실행하면 다음과 같습니다.

 

즉, 50개를 지정해도 최대 이미지 20장만 다운로드 된 것을 볼 수 있습니다.

 

 

 

코드를 수정 후 다시 실행하면 아래와 같이 이미지 50장이 모두 다운로드 되는 것을 확인 할 수 있으며,  그 이상으로 숫자를 늘려도 모두 다운로드 받을 수 있습니다.

 

 

50장 모두 다운로드 된 것을 보여주고 있습니다.

 

 


 

ㅁ 세부 내용

 

O 완성된 소스

 

 

소스 : 13.crawing_naver.py

 

# -*- coding utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time
from bs4 import BeautifulSoup
from datetime import datetime
import requests
import os
from datetime import datetime
import re



# 개선사항(숙제) 모두 해결한 소스임
# 9.인코딩된 이미지를 어떻게 다운로드하여 저장할 것인지
# 10.파일로 저장시 파일이름에 특수문자가 포함된 경우의 처리를 어떻게 할 것인지
# 11.이미지 저장시 현재폴더가 아닌 별도 폴더 생성 후 해당 폴더에 어떻게 저장할 것인지
# 12.폴더 이름을 현재시간을 사용해서 만들려면 어떻게 하면 되는지
# >예: img_20240301_113242
# 13.많은 이미지를 받을 경우 페이지를 내린 후 받아야 하는데 이를 어떻게 해결할 것인가?



##########################################
# 1.셀레니움을 이용한 크롬브라우저 자동 띄우기
##########################################
s = Service("C:/download/chromedriver.exe")  # Replace with the actual path
options = webdriver.ChromeOptions()
browser = webdriver.Chrome(service=s, options=options)


##########################################
# 12.폴더 이름을 현재시간을 사용해서 만들기
##########################################
# 현재 날짜를 가져오기
current_date = datetime.now().strftime("%Y%m%d_%H%M%S")

# 폴더 이름 생성
folder_name = f"img_{current_date}"


##########################################
# 11.이미지 저장을 위한 별도 폴더 생성 
##########################################
folder_path = os.path.join(os.getcwd(), folder_name)
try:
    os.mkdir(folder_path)
    print(f"폴더 '{folder_name}'가 생성되었습니다.")
except FileExistsError:
    print(f"폴더 '{folder_name}'는 이미 존재합니다.")
except Exception as e:
    print(f"폴더 생성 중 오류가 발생했습니다: {e}")



# 검색어
plusUrl = "강아지"
##########################################
# 2.네이버 검색 페이지 로딩하기
##########################################
baseUrl = 'https://search.naver.com/search.naver?where=image&sm=tab_jum&query='
url = baseUrl + plusUrl
print(url)

browser.get(url)
time.sleep(2)


##########################################
# 13.셀레니움을 이용해서 페이지 내리기
##########################################
j = 50 # 이미지 수
k = round(j/15) # 스크롤 내리는 횟수
# if k == 0:
#     k = 0

# 스크롤을 여러 번 내리려면 반복문을 사용
for i in range(k):  # 3번 스크롤을 내릴 예시
    # 자바스크립트를 사용하여 페이지를 스크롤
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    
    # 스크롤 후 로딩을 위해 충분한 시간을 기다릴 수 있도록 설정 (필요에 따라 조절)
    time.sleep(2)

# # 브라우저 종료
# browser.quit()

print("페이지 스크롤이 완료되었습니다.")




##########################################
# 3.네이버 검색 페이지에서 모든 소스 가져오기
##########################################
html_source = browser.page_source
# print(html_source,"\n\n\n\n++++++++++++++++++++++++++++++++++++++++++++++")
soup = BeautifulSoup(html_source, 'html.parser')
# print(soup)



##########################################
# 4.가져온 소스 필터링 테스트 하기
##########################################
# 가져온 소스에서 이미지 태크의 클래스 속성이 '_fe_image_tab_content_thumbnail_image' 인것을 가져와 보기
img = soup.find('img', {'class': '_fe_image_tab_content_thumbnail_image'})
# print(img)
# https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyNDAxMDhfOTEg%2FMDAxNzA0NjgzOTQwMTAx.JKnvEIv6ST9A9IW6iTtTtAR2MtkkBaRPlF_--TLfUfIg.KAh-qQql-eBqUuP2Kkb2yGj2pdSMNRVM3KosTAiTVdQg.JPEG.rkddl2001tmf%2Fth_%252817%2529.jpg&type=a340



############################################################
# 5.가져온 소스에서 이미지 링크와 설명만 뽑아서 리스트에 담아두기
############################################################
image_links = []
image_alts = []
for img in soup.find_all('img', {'class': '_fe_image_tab_content_thumbnail_image'}):
    image_links.append(img['src'])
    image_alts.append(img['alt'])
# print(image_links,"\n\n")
# print(image_alts)



############################################################
# 6.이미지 링크와 설명 가공하기(원하는대로 만들기)
############################################################
# j = 2 # 가져올 이미지 수
# result = list(zip(image_links[:j], image_alts[:j]))
# print(result,"\n")
# print(result[0],"\n")



############################################################
# 7.이미지를 다운로드하고, 이미지 파일이름 만들기
############################################################
for i, (link, alt) in enumerate(zip(image_links[:j], image_alts[:j]), start=1):
    # print(link)
    # link = link.split(':')[0]
    ############################################################
    # 9.인코딩된 이미지 제외하기
    ############################################################
    if link.split(':')[0] == 'https':
        img_data = requests.get(link).content
        filename = f'{i}_image_{str(alt)}.jpg'
        ############################################################
        # 10.파일이름에 특수문자 포함 시 처리하기
        ############################################################
        filename = re.sub(r'[^\w\s.]', '', filename)

        # 폴더변경(새로 생성한 이미지 폴더로 이동)
        os.chdir(folder_path)

        ############################################################
        # 8.PC에 다운로드한 이미지를 저장하기
        ############################################################
        try:
            with open(filename, 'wb') as f:
                f.write(img_data)
                print(plusUrl, "이미지가 내PC에 잘 저장되었습니다.")
        except:
            print(plusUrl, "이미지가 내PC에 잘 저장되지 않았습니다. 에러가 발생하였습니다.")

 

 

O 소스 실행

 
 - 소스파일 다운로드 후 cmd, 파워쉘 또는 vscode 등에서 아래와 같이 실행하시기 바랍니다.
 
 > python 13.crawing_naver .py

 

 


 

O 주요 내용

 

 

아래 소스에 대해 간략히 설명하면 다음과 같습니다.

 

line 72~83: 셀레니움에서 최초 브라우저를 띄우고 로딩(약 2초 이상)한 후 동적 페이지를 아래로 스크롤 해야만 다수의 이미지를 받을 수 있습니다. 여기서는 이미지의 수에 따라 페이지 다운의 횟수를 지정하였습니다.

예를 들어 다운로드 받을 이미지 수가 50개이면 50/15 = 3.3xx 인데, round()함수를 사용하면 3이됩니다. 따라서 이미지 50장 설정 시 페이지 다운은 3번 하게 됩니다.

line 80 : 페이지 다운은 아래 코드로 실행합니다.

browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")

 

line 83 : 페이지 다운 후 이미지가 제대로 로딩 될 수 있도록 반드시 여유 시간(time.sleep(2))을 주어야 합니다.

 

 

 

 

 

 

 

 

 


ㅁ 정리

 

O 우리가 배운 내용

 

 

 - 오늘 우리는 많은 수의 이미지(예: 강아지 100장 등)를 내려 받으려면 셀레니움을 이용하여 동적으로 페이지 다운 후 다운로드 해야 하는데, 이러한 동적 페이지 다운 방법에 대해 알아 보았습니다.

 

 - 오늘 우리가 배운 내용 중 가장 중요한 부분을 꼽으라면 아래와 같습니다.

아래 주석 참조

 
j = 50 # 이미지 수
k = round(j/15) # 스크롤 내리는 횟수
 
# 스크롤을 여러 번 내리려면 반복문을 사용
for i in range(k):  # 3번 스크롤을 내릴 예시
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(2)

 

 

-이것으로 '(실습)파이썬 네이버에서 강아지로 검색 후 강아지 이미지를 자동으로 크롤링 하는 프로그램 만들기'의 모든 강의를 마칩니다.

 
긴 글 읽어주셔서 고맙습니다.
 
 

 

오늘은 여기까지이며, 댓글하트는 제가 이글을 지속할 수 있게 해주는 힘이 됩니다.

 

 

감사합니다.

728x90
반응형
LIST