본문 바로가기

etc

한강수온 크롤링 (selenium,phantomjs,beautifulsoup)

@마크다운

# python selenium,beautifulsoup4를 사용을 기준으로 한 포스팅입니다.



한강수온을 체크하기 위해선 공공API가 있는지 부터 체크를 해야한다.

API가 있다면 작업을 사실 할게 없기 때문

유감스럽게도 한강수온은 API를 제공해주지 않는것 같았다( 있다면 알려주세요)

그래서 [실시간수질정보시스템](http://www.koreawqi.go.kr/index_web.jsp)을 실시간으로 크롤링하기로 했다.

[실시간수질정보시스템](http://www.koreawqi.go.kr/index_web.jsp)에 들어가보면 수계별 실시간 수질자료를 볼 수 있는데

여기서 구리측정소가 한강물온도가 되겠다.

간단하다.

이 사이트를 분석하고 저 수온만 빼내면 된다.

개발자 도구가 아닌 마우스 우클릭 -> 페이지 소스보기를 해보자.


```html

<!-- DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" --> 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> 

<html> 

<head> 

<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" /> 

<title> 실시간수질정보시스템 </title> 

<meta name="generator" content="editplus" /> 

<meta name="author" content="Cat" /> 

<meta name="keywords" content="실시간수질정보시스템" /> 

<meta name="description" content="수질정보시스템" /> 

<script type="text/javascript" src="../../js/ajax.js"></script> 

<script language="javascript" type="text/javascript"> 

//window.onload = initPage; //설문조사 

window.onunload = logoutOnWinClosed; 

// 화면을 초기화한다.(설문조사) 

//function initPage() { 

// window.open("/jsp/front/poll/2014/12/popup.jsp","research","location=0, width=485, height=525"); //설문조사 팝업 

//} 

// 브라우저가 임의로 닫힐 로그아웃한다. 

function logoutOnWinClosed() { 

doRequestUsingPOST("/wQSMLogin.wq", "action_type=U&action_type_seq=2"); 

} 

</script> 

</head> 

<frameset rows="*" cols="*"> 

<frame name="MainFrame" src="/wQSCHomeLayout_D.wq?action_type=T" scrolling="yes" title="main"/> 

<!-- frame name="MainFrame" src="/toWQSCLoginMainView.wq" scrolling="yes" / --> 

</frameset> 

</html>

```


뭔가 짧다..

개발자도구로 보면 이렇지 않다.

좀 더 살펴보면 우리가 원하는 정보느 frame태그안에 들어있다는걸 알 수 있다.

당연히 뷰티풀수프로 긁어봤자 위의 코드만 나오고 내용물은 보여주지않는다.

파이썬에서는 이러한 사이트들을 크롤링 할 수 있도록하는 selenium이라는 모듈이 존재한다.

```

pip install selenium

```

인터넷 사이트들을 실제 유저들이 클릭하는것처럼 컴퓨터가 동작하는 모듈이다.


selenium만으로는 뭔가 부족하다.

selenium이 사용할 드라이버 또한 다운받아야한다.

본인은 PhantomJS를 사용하지만 취향껏,상황껏 재주따라 알아서 다른 드라이버들을 쓰길바란다.


> PhantomJS는 웹 테스트를 위해 나온 헤드리스 브라우저이다(화면이 존재안함)


첫번째 방법 [다운로드](http://phantomjs.org/download.html)

두번째 방법

```

wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2

```

다운을 받았다면 실행파일을 적당히 옮겨주자(프로젝트 최상위라던가)

자 이제 본격적으로 크롤링을 해보도록 하겠다.


your script file

```

from selenium import webdriver

from bs4 import BeautifulSoup


driver = driver.webdriver.PhantomJS('실행파일의 경로')

```


변수의 이름은 재주껏 변경해서 쓰자


위와 같은과정이 끝났다면

```

from selenium import webdriver

from bs4 import BeautifulSoup


driver = driver.webdriver.PhantomJS('실행파일의 경로')

driver.get('http://www.koreawqi.go.kr/index_web.jsp')

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

print(soup)

```

이렇게 해보자

뭔가 이상하지 않는가?

왜 내용이 없지?

아까 페이지소스보기와 내용이 같다.

괜찮다. 이렇게 나오는게 정상이다.

우리가 홈페이지에 들어갔을땐 frame부분이 자동적으로 실행되어서 보이게 되었지만

selenium은 직접 보고있는곳을 바꿔줘야한다.

다시 스크립트에서

```

from selenium import webdriver

from bs4 import BeautifulSoup


driver = driver.webdriver.PhantomJS('실행파일의 경로')

driver.get('http://www.koreawqi.go.kr/index_web.jsp')

driver.switch_to.frame('MainFrame')

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

print(soup)

```

위 구문을 get이 끝난다음 넣어주고 다시 실행해보자


내용이 바뀌었는가?

바뀌지 않았다면 곤란하다.

어디선가 틀렸거나 오타,실수 등이 있는게 분명하다 디버깅을 해보도록하자.


잘 따라왔다면 우리가 원하는정보를 담은 페이지가 리턴되고 있는데

여기서 우리가 필요한것만 뽑아서 리턴하면 한강수온을 긁어올수 있다.

이제 필요한것이 [뷰티풀수프](https://cryptosan.github.io/pythondocuments/documents/beautifulsoup4/)이다.

첨부한 사이트로 가면 사용법이 주르르륵 나와있다.

직접 작성해서 뽑아내도 좋고

본인이 사용한 코드를 사용해도 좋다.


본인이 작성한 코드는 다음과 같다.

```

from selenium import webdriver

from bs4 import BeautifulSoup


driver = driver.webdriver.PhantomJS('실행파일의 경로')

driver.get('http://www.koreawqi.go.kr/index_web.jsp')

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

suon = soup.find('td', class_='start', text='구리').find_next_sibling("td").text

print(suon)

```

코드리뷰를 간단하게 하자면

리턴된 페이지의 내용중에서 td태그의 클래스이름이 start이면서 text가 구리인것만 뽑아내서 그다음 td태그의 text만 뽑아내도록 했다.


되게 간단해보이지만 저 한줄짜는데 30분걸렸다..

더 좋은코드는 얼마든지 있을수 있다.

코딩에는 정답이 없기때문


아무튼 이 포스팅을 읽고 누군가에게는 도움이 되었으면 하는 바램이다.