강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

민소리님의 프로필 이미지
민소리

작성한 질문수

[신규 개정판] 이것이 진짜 크롤링이다 - 실전편 (인공지능 수익화)

셀레니움 환경설정

웹 크롤링 대상중 웹에디터(smart_editor2) 안의 텍스트를 크롤링하는 방법

작성

·

117

0

수업을 적용하며 크롤링 연습을 하고 있는데, 웹 크롤링 대상중 웹에디(smart_editor2) 안의 텍스트를 크롤링하는 방법이 궁금합니다.

셀레니움을 활용하여 적용하고 있는데 웹에디터는 접근이 잘 안되고 접근이 된것 같은데 텍스트가 출력되지 않습니다 어떠헥 해야 할지 모르겠어서 질의 드려요

 

외부 접근되지 않는 사이트이고 아이디 비번은 마스킹 처리한 코드는 아래와 같습니다.

 

결국 아래 부분이 문제인것 같은데 에디터 내 텍스트 추출 방법을 몰라 문의드려요

    try:
        driver.switch_to.frame("iframe4dummy")  # 🔹 iframe 내부로 이동
        # 🔹 iframe 내부에서 특정 클래스("se2_inputarea")를 가진 body 태그 찾기
        # 🔹 iframe 내부의 `body` 태그에서 텍스트 가져오기
        body = driver.find_element(By.CSS_SELECTOR, "body")
        answer = body.text.strip()
        print("✅ HTML 에디터 내용:", answer)

        # 🔹 다시 원래 페이지로 복귀
        driver.switch_to.default_content()
    except Exception as e:
        print("❌ iframe 전환 실패 또는 body 태그를 찾을 수 없습니다:", str(e))

 

 

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from urllib.parse import urlencode  # URL 파라미터 추가용
import time
import random
import openpyxl

import requests
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

newscralling =[]
import pyautogui
import pyperclip

#크롬 드라이버 자동 업데이트
from webdriver_manager.chrome import ChromeDriverManager

# #브라우저 꺼짐 방지
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)

service = Service(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service = service)

# 웹페이지 해당 주소 주소이동
driver.implicitly_wait(2) #웹페이지가 로딩 될때까지 5초 대기
driver.maximize_window()
driver.get("https://OOO")

#아이디 입력창
id = driver.find_element(By.CSS_SELECTOR, ".submitLogin.text:nth-of-type(1)")
id.click()
pyperclip.copy("id")
pyautogui.hotkey("ctrl", "v")
time.sleep(0.3)
# id.send_keys(Keys.TAB)

# #비밀번호 입력창 직접입력  

# time.sleep(7)

pw = driver.find_element(By.CSS_SELECTOR, ".login ul li:nth-of-type(2) input")
pw.click()
# pw.send_keys("비밀번호")
pyperclip.copy("pass")
pyautogui.hotkey("ctrl", "v")

#로그인 버튼
login_btn = driver.find_element(By.CSS_SELECTOR, ".btnLogin")
login_btn.click()

time.sleep(1)

params = {
    "counselProcStatus": 2,
    "page": 1,
    "pageSize": 2
}

#SSL인증 비활성화에 대한 경고메시지 삭제
import urllib3
urllib3.disable_warnings()

qna_list_url = "https://OOO"+ urlencode(params)
driver.get(qna_list_url)

html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
articles = soup.select(".boardListStyle table tbody tr")

import openpyxl
from datetime import datetime
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "온라인상담_접수중"
ws.append(["date", "category", "title", "quest", "answer", "man", "status"])
crowling = []


for article in articles:
    title = article.select_one(".alignLeft a").text
    date = article.select_one(".boardListStyle table tbody td:nth-of-type(4)").text
    category = article.select_one(".boardListStyle table tbody td:nth-of-type(2)").text
    status = article.select_one(".boardListStyle table tbody td:nth-of-type(7)").text
    link =  'https://OOO/'+ article.select_one(".alignLeft a").attrs['href']
    title_link = f'=HyPERLINK("{link}", "{title}")'
    
    #상세 페이지 요청
    driver.get(link)
    time.sleep(2)  # 페이지 로딩 대기
    detail_html = driver.page_source
    detail_soup = BeautifulSoup(detail_html, 'html.parser')
    quest = detail_soup.select_one(".con_txt").text
    
    try:
        driver.switch_to.frame("iframe4dummy")  # 🔹 iframe 내부로 이동
        # 🔹 iframe 내부에서 특정 클래스("se2_inputarea")를 가진 body 태그 찾기
        # 🔹 iframe 내부의 `body` 태그에서 텍스트 가져오기
        body = driver.find_element(By.CSS_SELECTOR, "body")
        answer = body.text.strip()
        print("✅ HTML 에디터 내용:", answer)

        # 🔹 다시 원래 페이지로 복귀
        driver.switch_to.default_content()
    except Exception as e:
        print("❌ iframe 전환 실패 또는 body 태그를 찾을 수 없습니다:", str(e))




    #answer = detail_soup.select_one(".se2_input_area.husky_seditor_editing_area_container iframe").text
    man = detail_soup.find('th', string="작성자").find_next_sibling().text
    crowling = ws.append([date, category, title, quest, answer, man, status])


    driver.back()  # 브라우저에서 '뒤로 가기' 실행

    print(date, category, title, quest, answer, man, status)

now = datetime.now().strftime("%Y%m%d_%H%M%S") 
filename = f"온라인상담_{now}.xlsx"

wb.save(filename)

답변 1

1

스타트코딩님의 프로필 이미지
스타트코딩
지식공유자

안녕하세요 사이트 주소가 없어서 HTML 구조나 문제상황등이 확인이 되지 않아
제가 직접 답변하는게 어렵네요 ㅠ

o1 모델의 답변을 첨부해 드립니다!

에디터 내부에 글 내용이 제대로 보이지 않거나 추출이 안 되는 주요 원인은 다음과 같습니다

  1. iframe을 정확히 인지/전환하지 못한 경우

    • 스마트에디터는 내부에 여러 개의 iframe을 사용하거나, 숨겨진 iframe이 있을 수 있습니다

    • driver.switch_to.frame("iframe4dummy")에서 iframe4dummy가 진짜 본문을 담고 있는 iframe인지 먼저 개발자도구(F12)로 확인해야 합니다

    • iframe을 찾을 때는 정확한 id 혹은 name, 또는 driver.find_element(By.CSS_SELECTOR, "iframe.클래스명") 식으로 지정해야 합니다

  2. 프레임 내부 구조가 단일 body가 아닐 수도 있음

    • 실제 텍스트가 <div> 태그 안에 있거나, 다른 자식 요소에 들어 있을 수 있습니다

    • 예: <body><div class="se_editView ..."><p>...</p></div></body> 구조처럼 body 아래에 별도의 wrapper가 있는 형태

    • 따라서 body.text가 아니라 div.se_editView 같은 실제 글이 담긴 요소를 찾아 .text로 가져와야 할 때가 많습니다

  3. 페이지 로딩 완료 전에 접근해서 요소를 못 찾는 경우

    • 에디터나 iframe이 동적으로 로딩되고 있어서 아직 요소가 준비되지 않은 상태일 수 있습니다

    • 이 경우 WebDriverWait을 통해 해당 요소가 나타날 때까지 기다려야 합니다

  4. 위 에디터가 정말 smart_editor2인지 확인 필요

    • 실제로는 다음 에디터 or CKEditor, 혹은 다른 버전일 수도 있으므로 구조가 조금씩 다릅니다

    • 개발자도구로 구조를 확인한 뒤, iframe 안의 body(혹은 div 등)를 제대로 찾아야 합니다

아래 예시는 기본적인 방식입니다

# iframe에 들어갈 때는 프레임 요소부터 찾습니다
iframe_elem = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "iframe4dummy"))  # 혹은 By.NAME, By.CSS_SELECTOR 등
)
driver.switch_to.frame(iframe_elem)  # 해당 프레임으로 전환

# 스마트에디터 본문을 실제로 담고 있는 태그(예: div.se_editView) 확인
# 개발자도구로 body 이하의 실제 본문 클래스를 확인해 봅니다
content_elem = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "body"))  
)
content_text = content_elem.text.strip()

print("HTML 에디터 내용:", content_text)

# 다시 메인 프레임으로 복귀
driver.switch_to.default_content()

 

만약 body 태그에서 내용이 전혀 안 보인다면, 아래처럼 body 안쪽에 있는 다른 태그(예: div.se_editView)에 텍스트가 들어있을 가능성이 높습니다

content_elem = driver.find_element(By.CSS_SELECTOR, ".se_editView")
content_text = content_elem.text.strip()

 

혹은 <p>, <span> 등 세부 태그에 나뉘어 있을 수도 있으니, 구조를 개발자도구(F12)로 먼저 꼼꼼히 확인하는 것이 제일 중요합니다

추가로, iframe이 여러 개 있는 경우도 체크해야 합니다

  • 스마트에디터가 iframe4dummy, iframe4placeholder 등 여러 iframe을 두고, 실제 텍스트는 다른 iframe에 들어가 있을 수 있습니다

  • 따라서 iframe 이름이나 id 값을 잘 확인해서 정말 본문을 가진 프레임에 들어가는지 확인해야 합니다

정리하자면, “에디터 본문을 담고 있는 정확한 iframe을 찾아서 전환한 뒤, 정확한 요소(태그)를 찾은 다음 .text 또는 .get_attribute("innerText") 같은 방식으로 텍스트를 추출”하면 됩니다
에디터 구조만 파악되면 지금 쓰신 코드 자체는 크게 수정 없이 잘 동작할 거예요

도움이 되었길 바랍니다
즐거운 크롤링 하시고, 추가로 궁금한 점이 있으시면 언제든 말씀해 주세요
감사합니다

민소리님의 프로필 이미지
민소리
질문자

2중 iframe구조였었어요~ 말씀해주신 것처럼 html 구조 분석이 매우 중요한 것 같아요~ 정말 감사합니다.

민소리님의 프로필 이미지
민소리

작성한 질문수

질문하기