티스토리 뷰

171122 


(1) Python 웹 크롤링으로 정보 수집하기
  
성균관대학교 멋쟁이사자처럼 5기 - 2학기 프로젝트
  
학교를 몇 년 다니고 있지만, 
딱히 관심을 갖고 보지 않으면 
대학교 학생회가 어떤 공약을 제시했고, 얼마나 이행했는지 알기가 쉽지 않다. 

프로젝트 주제 선정 과정에서 이 문제를 해결해보면 좋겠다는 이야기가 나왔고,
2014년부터 2017년까지, 4년간 총학생회와 단과대 학생회의 공약 정보를 조사하기로 했다.

이 문제를 해결하려면 어떤 과정이 필요할지 대강 그려봤다.


1. 매년 총학생회와 단과대 공약 데이터를 저장해 두는 무언가를 찾는다.
2. 조사한 데이터를 웹페이지에 활용할 수 있는 데이터베이스 형태로 만든다.
3. 데이터베이스를 활용한 웹페이지를 만든다.


이 웹페이지가 만들어지기 위해 가장 중요한 것이 바로 공약 데이터다. 그렇다면 성균관대학교에서 매년 총학생회와 단과대 학생회의 공약을 저장하는 곳을 찾아봐야 했다. 


성균관대 선거관리위원회나 학교 내 학생지원팀에게 연락해보려 했으나, 이 프로젝트를 시작한 시기인 11월은 총학생회 선거가 있는 달이었다. 게다가 한창 일을 시작해야 할 프로젝트 초기가 11월 하순으로, 정말 선거가 며칠 앞으로 다가온 시기였다. 선거관리위원회는 이미 일하느라 정신없을 것 같고, 학생지원팀 입장에서도 선거가 코앞이다 보니 도움을 기대하기 어려울 것 같았다.


지인들에게 수소문한 결과 성대신문에서 매년 총학생회의 공약 이행여부를 평가하고 있다는 사실을 알게 됐다. 그렇다면 성대신문 웹페이지 크롤링 후 스크래핑하면 정보를 얻을 수 있을 것이다.


성대신문 웹페이지를 들어가서 확인해봤다.
http://www.skkuw.com/news/articleList.html
기사 중에서도 보통 ‘기획보도’에 학생회 관련 기사가 많으니, 기획보도를 중점적으로 확인해보기로 했다.


크롬 개발자도구로 확인해본 결과, 다행스럽게도 성대신문 웹페이지는 자바스크립트 기반 동작이 아니라 html과 css로 이루어져 있었다. 이 정도면 크롤링에 큰 어려움은 없다.

먼저, 필요한 라이브러리를 가져온다.
jupyter notebook을 활용했다.



import requests from bs4 import BeautifulSoup4 import chardet import datetime import pandas as pd import numpy as np #그리고 DataFrame으로 만들기 위한 array를 몇 개 정의한다. datearray=[] title=[] author=[] 

href=[]


url = "http://www.skkuw.com/news/articleList.html" for i in range(1,55): querystring = {"page":i, #url 뒤에 있는 parameter에서 변형하면 되는 건 page 변수 하나뿐이다. "total":"1093", "sc_section_code":"S1N2", "sc_sub_section_code":"", "sc_serial_code":"", "sc_area":"", "sc_level":"", "sc_article_type":"", "sc_view_level":"", "sc_sdate":"", "sc_edate":"", "sc_serial_number":"", "sc_word":"", "sc_word2":"", "sc_andor":"", "sc_order_by":"I", "view_type":"" } headers = { 'accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", 'accept-encoding': "gzip, deflate", 'accept-language': "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7", 'cache-control': "no-cache", 'connection': "keep-alive", 'cookie': "PHPSESSID=881f1642a92a997af2c6a5bf978e976d", 'host': "www.skkuw.com", 'referer': "http://www.skkuw.com/news/articleList.html?page=2&total=1093&sc_section_code=S1N2&sc_sub_section_code=&sc_serial_code=&sc_area=&sc_level=&sc_article_type=&sc_view_level=&sc_sdate=&sc_edate=&sc_serial_number=&sc_word=&sc_word2=&sc_andor=&sc_order_by=I&view_type=", 'upgrade-insecure-requests': "1", 'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36", 'page': "1", 'total': "1093", 'sc_section_code': "S1N2", 'sc_order_by': "I", 'postman-token': "04862f8b-61e1-e890-785d-cd4d8d74b1c7" } response = requests.request("GET", url, headers=headers, params=querystring) response.raise_for_status() response.encoding='euc-kr' html=response.text #request 라이브러리로 성대신문 페이지를 1 ~ 55페이지까지 각각 가져온다. #171122일은 55페이지가 마지막이었지만, 포스팅하는 지금은 아마 더 많을 것이다. for word in bs.select ('td.View_SmFont.FontEng'): array=word.string date=datetime.datetime.strptime(array,"%Y-%m-%d").date() datearray.append(date) #게시글의 시간을 스크래핑해서 datetime으로 정의한 다음, date array에 넣음 for text in bs.select('td.ArtList_Title > a'): titleword=text.string title.append(titleword) #html a tag의 string을 추출해 title이라는 array에 append했다. link='http://www.skkuw.com/news/'+text['href'] href.append(link) #게시글 상세 url 주소 a tag에서 수집해, href array에 append했다. raw_data={'title':title, 'date':datearray, 'link':href } #title, date, link 세 개의 array를 하나의 dictionary로 만들고, data=pd.DataFrame(raw_data) #해당 dictionary를 DataFrame으로 변환하면 Table 형태 데이터가 완성된다. 

data


위 코드를 실행하면 11월 22일 기준, 다음과 같은 결과를 얻을 수 있다.



이 중에서는 총학생회 공약과 관계없는 신문기사도 많다. 총학과 관련 있을 법한 기사들만 따로 추려냈다.


공약=data.loc[data.title.str.contains('공약|총학생회|총학|평가|학생자치')==True,:].reset_index(drop=True) #데이터 중 'title'안에 공약, 총학생회, 총학, 평가, 학생자치라는 단어가 하나라도 들어가 있는 데이터만 빼내서 정렬했다. 공약.to_excel('공약데이터.xlsx') 

#엑셀 파일로 저장


위 코드를 통해 엑셀 파일로 데이터를 추출할 수 있다.
데이터 양이 많은 편이 아니어서, 굳이 2014년부터 2017년까지의 데이터만 코드로 따로 빼내는 작업은 하지 않았다.

이제, 이 url 중에서 총학생회와 학생자치기구의 공약을 평가한 게시글을 찾아서 정리하면 
기본 데이터는 완성된다. 그 다음, c9 프로젝트에 데이터베이스로 옮기는 작업을 해야 한다.


댓글
댓글쓰기 폼