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

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE

작성한 질문수

실습으로 끝장내는 웹 크롤링과 웹 페이지 자동화 & 실전 활용

검색어 입력 관련

작성

·

408

1

연습삼아 나라장터의

상단 부분에 셀레니움을 통해 특정 검색어를 입력 후 검색을 실행 하려합니다

관련하여, 해당페이지 접속 후 단순히 find.element를 통해 driver.find_element(By.ID,"AKCKwd").sendkeys("검색어")

Screen Shot 2023-03-01 at 12.14.34 PM.png

와같이 사용할 수는 없는 것 인지요?

답변 3

3

(지나가다 답변 남깁니다^^)

send_keys를 사용하시면 됩니다.

질문에는 언더스코어가 빠져 있네요.

 

나라장터 크롤링 예제를

예전에 유튜브에 한 번 올린 적이 있었는데

영상 참고하시라고 링크 하나 남겨봅니다.

https://youtu.be/-301i3fHF4c

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE
질문자

감사합니다.

send_keys()는 위에 질문시 타이핑 오류가 있었네요^^

실제 코드에는 해당 오류가 없었는데도 불구하고 작동되지 않더군요
올려주신 영상을 보다을 참고 하여 input 태그 경로를 넣어도 여전히 입력에 문제를 격고 있습니다.

다른 조언 점 있으시면 조언 주시면 감사하겠습니다.

 

#기존코드

searchelement =  driver.find_element(By.ID,"search")
searchelement.find_element(By.ID,"AKCKwd").send_keys("test")

#영상
driver.find_element(By.CSS_SELECTOR,"input#AKCKwd.keyword").send_keys("test")

해당 엘리먼트는 iframe 안에 들어있기 때문에
switch_to로 먼저 "maintop_iframe" 안으로 진입하신 후, input 엘리먼트에 접근하실 수 있습니다.

driver.switch_to.frame("maintop_iframe")
driver.find_element(By.ID,"AKCKwd").send_keys("test")

제 영상 촬영 시점에는 maintop_iframe"이 아니고 프레임 이름이 "sub"였네요. 이렇게 종종 바뀝니다ㅎㅎㅎ

 

 해당 iframe에서 나오려면

driver.switch_to.parent_frame()

등으로 빠져나오실 수 있습니다.

 

유난히, 정부제작 사이트를 크롤링 하시다 보면
프레임 안에 프레임이 중첩되어 있는 경우도 많고,
A프레임 안에 B엘리먼트, C프레임 안에 D엘리먼트를 순차접근해야 하는 경우도 종종 있습니다.
프레임 스위칭에 익숙해지시면 셀레늄 크롤링이 한결 쉬워지실 겁니다.

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE
질문자

감사합니다 많은 도움이 되었습니다 ^^

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE
질문자

안녕하세요.

나라장터 크롤링 관련하여,

쭉 진행하여 보다 도저히 해결되지 않는 부분이 있어 한참 지난 시점에서 한 가지더 문의 드려도 될지요?

 

셀레니움을 통한 페이지 이동 관련인데요 .

 

하기와 같이 X path를 통하여, 페이지를 이동할 경우 1번의 이동 ex(1 -> 2 or 1->10)

지와 같이 이동은 되는데 이후 이동은 에러가 나더군요

아래와 같이 2가지 방법을 시도 하여 보았습니다.

  1. 반복문을 통한 페이지 이동


pagenumclass = driver.find_element(By.CLASS_NAME,"pagination")

# #[1~11] , 11나오면 Next page 및 Pagenumber Update
# pagenumbers = list(range(2,12))
# nextpagetrigger = pagenumbers[9]

# ###페이저 넘버 ex 11~21 함수###
# variablenum = list(range(0,10))
# def pagenumtransform():
#     for num in variablenum:
#         pagenumbers[num] += 10


# #Pagenum = 2
# #pagenumclass.find_element(By.XPATH,f"//a[@href='javascript:gotoPage({Pagenum});']").click()

# #페이지 이동 기능 
# for clicknum in pagenumbers:
#     if clicknum == nextpagetrigger:
#         pagenumclass.find_element(By.CLASS_NAME,"page_next").click()
#         time.sleep
#         pagenumtransform()
    
#     else:
#         pagenumclass.find_element(By.XPATH,f"//a[@href='javascript:gotoPage({clicknum});']").click()
#         time.sleep(2)
  1. 각 페이지 넘버를 통한 이동

pagenumclass.find_element(By.XPATH,f"//a[@href='javascript:gotoPage(2);']").click()
time.sleep(2)
pagenumclass.find_element(By.XPATH,f"//a[@href='javascript:gotoPage(3);']").click()

하지만 모두 한번 의 페이지 이동 후 문제가 발생 하더군요 Frame은 같은 곳에 있 것 같은데 어떠한 해결 책이 있을지요?

해당 태그는 페이지가 이동 또는 새로고침되고 나면 다시 탐색을 해 주셔야 합니다.

(그런데, 속도도 느리고 비효율적이기 때문에)

일반적으로 이런 경우 가장 좋은 방법은 아래 예시코드와 같이

페이지 이동 자바스크립트 코드를 웹드라이버에서 직접 실행하는 것입니다.

예를 들어 100페이지까지 특정 작업을 반복하신다면,

for page in range(1, 100):
   driver.execute_script("javascript:doPostPg({page});")  # 페이지 이동 후
   # 특정작업

해결이 되었기를 바랍니다.

혹시 행정직이시면
제 아래아한글 자동화 강의도 한 번 구경하고 가시길 바랍니다^^
https://inf.run/DopA

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE
질문자

감사합니다.

추천 주신 강의는 근시 일내 참고하여 보도록 하겠습니다. ^^

다시 한번 답변 정말 감사드리며 한걸음 한걸음 해결 하고 있으나 문제의 연속인 것 같습니다.

조언 주신 driver.execute_script()를 통해 셀레니움상 페이지 변환은 잘 되나, BS4로 데이터를 불러오는 것은 1page 소스만 반복 적으로 불러오는 문제가 또 발생하는군요'';

driver.switch_to.frame 은 페이지 이동 후 재 실행 하려 하니 해당 부분은 오류가 나고

기본 url 및 frame 타이틀은 변화 없이 리스트 항목만 js로 바뀌는데 이러한 경우는 어떻게 페이지 이동 후 처리를 해주어야 하는 것 일지요?

1

(굳이) bs4를 사용하셔야 한다면

soup = BeautifulSoup(driver.page_source, 'html.parser')

라고 사용하시고,

개인적으로 동적 페이지 크롤링은

그냥 셀레늄 안에서 find_elements 등으로 해결하시는 것을 추천드립니다.

 

나라장터 같은 경우, 페이지를 이동한 후에도 프레임 위치는 유지되므로

페이지 이동시마다 switch_to를 실행하지 않으셔도 됩니다.

다만, 페이지 로딩 오류로 인해 최상위프레임으로 이동해버리는 경우가 간혹 있을 수도 있으므로

어느 정도 테스트해보시면서 프레임이 튕긴다 싶으면 그 때는 아래처럼

try:
    driver.switch_to.frame(...)
except 해당오류종류 as e:
    pass

식으로 적당히 처리하셔도 됩니다.

 

구체적으로 어떤 작업을 하고 계신 건지요?

 

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE
질문자

감사합니다

조언 주신 부분을 바탕으로 어느정도 해결을 했네요.

 

작업은 특별한 것은 아니고 특정 키워드에 대한 공고를 전체 다 불러와서 좀 정리해보는 연습을

하고 있습니다.

1

김플님의 프로필 이미지
김플
지식공유자

일코님 말씀처럼 send_keys를 사용하시면 됩니다.

SANGYUN LEE님의 프로필 이미지
SANGYUN LEE

작성한 질문수

질문하기