20. [ selenium의 webdriver() / implicitly_wait() / WebDriverWait() + EC + By ==> bs4 ]를 이용한 연결된 페이지를 타고가서/기다렸다가 ==> 추가정보를 scrapping하는 crawling
2019. 1. 3. 14:01
파일명 : watch_court.py
필요파일 : 크롬드라이버.exe
나만의 beautifulsuop 객체에 대한 정의
- ?.태그명 : 해당 태그 하위 전체구조들까지 다 가져오기 ex> soup.body
- 태그명.find_all( '태그명' ) : 하위의 모든 태그 중 여러개의 특정 태그를 리스트로 가져오기 ex> .find_all('tr')
- 태그명.find( 속성 = '특정 속성명' ) : 하위의 모든 태그 중 특정 속성으로 검색 ex> .find(id = 'ea_list')
- 태그명.get('속성') : 해당 태그안의 속성의 내용물을 가져옴 ex> a.get('href')
19.에서 했던 web_scrapping_example.py에 대해서,, 게시판 링크를 타고 추가 정보도 가져와야할 상황이다.
즉, 게시판을 클릭에서 그 글속에 정보도 가져와야한다.
- 먼저, 1 ~ 100page까지 스크래핑했던 for문을 range(1, 2)까지로 줄이자. ( 다 완성된 뒤 100으로 수정하자)
- # TODO 를 활용하였다. - 게시판의 각 줄을 의미하는 line안의 각 칸<td> 중 게시글 제목칸인 td_list[1]를 보자.
.text제외시키고 제목칸 <td>태그 안에는 링크 주소태그 <a> 태그가 있다. - *** my) 만약, 이것을 bs4로 scrapping으로 처리한다면, 클릭해서 게시판으로 들어가는 시간 등을 처리 못하게 된다.
*** 또한, href주소를 main url 뒤에 붙혀넣은 뒤, 홈페이지의 주소가 다르게 바뀌는 것 또한 문제를 발생시킨다
그래도 한다고 가정하고 시행해보면, - td 태그의 a태그로 이동 : td.a
- a 태그의 href 속성의 내용물 가져오기 : a.get('href)
- ***여기서 /뒤의 주소는 원래 웹사이트의 메인url인 http://watch.peoplepower21.org 뒤에 달리는 것이다.
*** 하지만, 홈페이지가 로딩이 완료되면 주소가 변해있다.
*** 이로 인해 문제가 발생할 것이다. - 이제 main url + href의 문자열을 합한 url을 requests.get() -> response.text -> html-> soup -> body 로 접근할 수 있다.
*** 하지만, 데이터 로딩중이라는 문구와 함께 body치고는 너무 짧은 태그들만 보인다.
*** 그 이유는 href를 이용한 url은 로딩을 준비하는 페이지로 가기 때문이다. - 이럴 때 사용하는 것이 selenium이다.
selenium의 webdriver & chromedriver 설치
- 설치
- from selenium import webdriver
- 웹드라이버 중 크롬드라이버 이용을 위한 browser객체 만들기
*** 첫 실행시 오류가 뜬다. 에러 중 마지막 줄 사이트로 이동해서 크롬드라이버 최신버전을 설치하자. - 크롬드라이버 설치
https://sites.google.com/a/chromium.org/chromedriver/home
압축푼 파일을 해당 파이참 프로젝트 안에 붙혀넣기하자. - 다시 한번 크롬드라이버 객체browser를 생성하는 것을 실행시켜보자.
- 크롬창이 하나 뜨면서 자동화된 테스트 소프트웨어에 의해 제어되고 있다고 뜬다.
- 크롤링이 다 끊나고 browser도 꺼져야 하므로, py파일 맨 마지막에 browser.quit를 생성과 동시에 적어주는 버릇을 들이자.
selenium - webdriver - chromedriver를 이용해서 연결페이지를 가서 추가정보 가져오기
- 앞에서 시도 했던 부분 중 게시글td태그안의 a태그 -> href내용물 가져오기의 코드만 살려놓는다.
- sele - web- chromedriver로 페이지를 타고 갈 때는, requests.get( url )부분을 대체하여 사용하는 것이다.
- url을 얻은 상태에서 browser.get( url )시작한다.
- 현재 상태로 실행하면, 작업은 없지만 연결된 페이지가 로딩이 완료되고, 다음 loop로 가는 것을 확인할 수 있다.
- 그 이후에는 - browser.get(url)로 받은 반응은 response = requests.get(url) 에 대응되고
변수없이 browser객체에 할당된 반응은
html = broswer.page_source 를 통해 html을 받아와야한다. 이것은 html = response.text에 대응된다. - html을 받았으면, 이전과정과 똑같이, beautifulsoup을 통해 스크래핑 하면 되는 것이다.
- body 이후에서는 무엇을 가져와야할지(이전에는 게시판 첫 글을 검색) ctrl + u 를 통해 필요한 내용물의 자리를 살펴보자.
- 우리는 해당 페이지에서 발의자라고 써있는 부분을 찾아보자. - 우리가 필요한 발의자들 목록의 상위에서 많은 <div>태그들 가운데 id를 가지고 있는 <div>태그가 보인다.
id는 한 페이지당 고유값이므로 body에서 .find(id = )로 한방에 타고들어간다.
또한, 해당id <div>태그만 찾으면, 안에 text내용물은 발의자 목록 밖에 안보이므로, 쉽게 내용물을 가져올 수 있을 것 같다.
하지만, 내용물이 제대로 안보인다.
.text는 하위태그의 텍스트를 다 가져오긴 하지만,
단지, selenium-webdriver-chromedriver가 페이지로딩이 완료가 다되고, 다음loop를 도는 기능은 있으나,
selenium이 최종 페이지를 로딩하자마자, 바로 다음 loop로 넘어가는 식으로 수행하기 때문에
bs4가 스크래핑할 시간이 없게 된다. - 이 때, 사용하는 것이 크롬드라이버의 객체 broswer를 이용한 암묵적인 기다림을 의미하는 .implicitly_wait( )이다.
필요한 html코드를 페이지에서 받아오기 전, 5초를 기다려준다고 해봤다.
하지만, 로딩되자마자 떠나는 것이 문제이므로 이것은 해결책이 안된다.
Selenium의 WebDriverWait() + EC + By클래스를 이용하여 특정속성의 출현 확실히 기다려주기
- selenium이 로딩되자마자 떠나는 것을 방지하기 위해,
해당id태그가 확!실!히! 출현한 이후에---> 다음loop로 빠져나가도록 해주는 selenium의 클래스는 3가지가 필요하다.
- By. 대문자 ID - WebDriverWait()를 쓰면, 무조건 html정보에 id = collapseTwo 이하의 태그들이 포함되어 있다.
bs4는 그 정보를 가져온다. 마치 아래처럼 텍스트가 없는 것 처럼 보이나..
빈칸이 너무 많아서... 콘솔을 오른쪽으로 돌려보면 있다 - 이제, 발의자 정보를 2차원 리스트에 추가로 append시킬 수 있도록
1) append구문을 bs4로 스크래핑 한 뒤쪽자리로 옮기고
2) pandas의 칼럼 역시 추가해준다. 이 때, 수기로 추가해주자.
저장된 엑셀파일을 확인하면 아래와 같다. 하지만,,, 빈칸이 너무나도 많다. - 빈칸을 없애주기 위한 .replace( ' ', '')
- 마지막으로 page를 수정해서 10page까지만 해보자.
'빅데이터 관련 프로그래밍 > Python3 기초 및 업무자동화' 카테고리의 다른 글
19. requests.get('')으로 url속 html 받아온 뒤 -> bs4를 이용한 < 해당페이지 scrapping > (0) | 2019.01.01 |
---|---|
18. BeuatifulSoup4 설치 및 예제 홈페이지 스크래핑 해보기 (0) | 2018.12.30 |
17. 웹스크래핑 시작하기 - HTML 이해 / CSS from bootstrap (0) | 2018.12.30 |
16. pandas를 이용해 차트그리기 (1) | 2018.07.11 |
15. pandas로 excel파일 읽고 / 쓰기 (0) | 2018.07.09 |