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

코딩초보님의 프로필 이미지

작성한 질문수

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

-

for문에서 창 전환 후 에러 해결 방법 문의

작성

·

1.3K

0

 

from selenium import webdriver # webdriver 불러오기
from selenium.webdriver.chrome.options import Options # 브라우저 닫힘 방지
from selenium.webdriver.chrome.service import Service # 크롬드라이버 다운로드(새로운 버전 다시 받을 필요 없음)
from webdriver_manager.chrome import ChromeDriverManager # 크롬드라이버 다운로드(새로운 버전 다시 받을 필요 없음)
import time
import pyautogui
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys




options = Options()
options.add_experimental_option('detach', True)  # 브라우저 바로 닫힘 방지
options.add_experimental_option('excludeSwitches', ['enable-logging'])  # 불필요한 메시지 제거

service = Service(ChromeDriverManager().install())

 #service = Service(ChromeDriverManager().install()) 이 부분을 
 # ChromeDriverManager(path="원하는 경로") 이렇게 사용하면 원하는 곳에 
 # 크롬드라이버를 다운로드하게 됩니다.

driver = webdriver.Chrome(service=service, options=options)


driver.get("https://www.g2b.go.kr:8101/ep/tbid/tbidFwd.do")
time.sleep(2)
search_click = driver.find_element("#bidNm").click()
keyword = pyautogui.prompt("<<<검색어를 입력하세요 >>>")
search_keyword = driver.find_element(By.CSS_SELECTOR,"#bidNm").send_keys(keyword)
output_num = driver.find_element(By.CSS_SELECTOR,"#recordCountPerPage").click()
output_num_select = driver.find_element(By.CSS_SELECTOR,"#recordCountPerPage > option:nth-child(5)").click()
search_btm_click = driver.find_element(By.CSS_SELECTOR,"#buttonwrap > div > a:nth-child(1)").click()

bid_infors = driver.find_elements(By.CSS_SELECTOR,"tbody tr")

for bid in bid_infors :
    title = bid.find_element(By.CSS_SELECTOR,"td:nth-child(4) > div > a").text
    link = bid.find_element(By.CSS_SELECTOR,"td:nth-child(4) > div > a").get_attribute('href')
    client = bid.find_element(By.CSS_SELECTOR,"td:nth-child(5) > div").text
    print("공고명 : ", title)
    print("주소 : ", link)
    print("발주처 : ",client )
    print()


# 사전규격 크롤링

driver.get("https://www.g2b.go.kr:8081/ep/preparation/prestd/preStdSrch.do")
time.sleep(2)

keyword2 = pyautogui.prompt("<<<검색어를 입력하세요 >>>")
search_keyword2 = driver.find_element(By.CSS_SELECTOR,"#prodNm").send_keys(keyword2)
output_num2 = driver.find_element(By.CSS_SELECTOR,"#recordCountPerPage").click()
output_num2_select2 = driver.find_element(By.CSS_SELECTOR,"#recordCountPerPage > option:nth-child(5)").click()
search_btm_click2 = driver.find_element(By.CSS_SELECTOR,"#frmSearch1 > div.button_wrap > div > a:nth-child(1)").click()

bid_infors2 = driver.find_elements(By.CSS_SELECTOR,"tbody tr")

for bid2 in bid_infors2:
    title2 = bid2.find_element(By.CSS_SELECTOR, "td:nth-child(4) > div > a").text
    client2 = bid2.find_element(By.CSS_SELECTOR, "td:nth-child(5) > div").text
    link_click = bid2.find_element(By.CSS_SELECTOR, "td:nth-child(4) > div > a").click()
    time.sleep(2)  
    link2 = driver.current_url
    print("공고명 : ", title2)
    print("주소 : ", link2)
    print("발주처 : ",client2)
    print()

    driver.back()  
    time.sleep(2)  

위 코드에서 발생하는 코드는 아래와 같습니다. 

Traceback (most recent call last):
  File "c:\coding\나라장터크롤링\1.입찰공고크롤링.py", line 61, in <module>
    title2 = bid2.find_element(By.CSS_SELECTOR, "td:nth-child(4) > div > a").text
  File "C:\Users\landj\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 425, in find_element
    return self._execute(Command.FIND_CHILD_ELEMENT, {"using": by, "value": value})["value"]
  File "C:\Users\landj\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 403, in _execute
    return self._parent.execute(command, params)
  File "C:\Users\landj\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 440, in execute
    self.error_handler.check_response(response)
  File "C:\Users\landj\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 245, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

이것 저것 다해봐도 안되네요...해결 방법을 알려주시면 감사하겠습니다.

답변 1

0

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

bid_infors2 = driver.find_elements(By.CSS_SELECTOR,"tbody tr")

driver.back()을 할 경우 기존에 가지고 있던 태그객체 정보를 잃어 버립니다.

(원래 페이지에 있는 태그가 뭐였지?라고 오류가 뜨는 경우였어요)

 

리스트 목록을 다시 찾는 방식으로 구현해 봤습니다.

bid_infors2 = driver.find_elements(By.CSS_SELECTOR,"tbody tr")
i = 0
while i < len(bid_infors2):
    title2 = bid_infors2[i].find_element(By.CSS_SELECTOR, "td:nth-child(4) > div > a").text
    client2 = bid_infors2[i].find_element(By.CSS_SELECTOR, "td:nth-child(5) > div").text
    link_click = bid_infors2[i].find_element(By.CSS_SELECTOR, "td:nth-child(4) > div > a").click()
    time.sleep(2)  
    link2 = driver.current_url
    print("공고명 : ", title2)
    print("주소 : ", link2)
    print("발주처 : ",client2)
    print()

    driver.back()  
    time.sleep(2)  
    bid_infors2 = driver.find_elements(By.CSS_SELECTOR,"tbody tr")
    i += 1

time.sleep은 네트워크 환경에 맞게 조금 줄여도 괜찮을 듯 합니다.

코딩초보님의 프로필 이미지
코딩초보
질문자

강사님 친절한 답변 감사드립니다..수정해서 진행해보겠습니다.~

코딩초보님의 프로필 이미지
코딩초보
질문자

잘 작동됩니다. 왜 이걸 생각 못했을까..ㅎ..아직 길은 멀지만 열심히 해보겠습니다. 감사합니다.~