Download presentation
Presentation is loading. Please wait.
Published byAlexander Bakken Modified 5년 전
1
Ruby Programming 8 Web Crawling 한국어 정보의 전산 처리
2
Web Crawling의 요소 기술 웹에 접속하여 웹문서 읽어오기 웹문서 분석 날짜 처리 반복/재귀 알고리즘
open-uri나 net/http 라이브러리 이용. 웹문서 분석 xml/html parser 라이브러리(예: nokogiri)를 이용할 수도 있으나 간단한 분석일 때는 scan 등의 함수로 정규표현을 검색하여 처리할 수도 있음. 날짜 처리 url이 날짜를 바탕으로 할 때는 Date 클래스로 날짜 처리. 반복/재귀 알고리즘 수많은 웹페이지를 방문할 때에는 iterative 또는 recursive 알고리즘을 사용해야 함.
3
조선일보 스포츠 기사 제목 읽어오기 조선일보 홈페이지 ‘메뉴 전체보기’를 클릭하여 ‘스포츠 - 전체’를 선택 날짜를 클릭
날짜를 클릭 하루당 스포츠 웹페이지가 여러 페이지로 이루어져 있고 한 페이지당 20개의 기사 요약이 제시됨. 각 기사의 제목만 추출하고자 함. 조선일보 홈페이지 html 파일의 인코딩은 euc-kr이므로 iconv를 이용하여 출력 결과를 utf-8로 변환하여 출력
4
기사의 html 구조 html 소스 코드를 보면, 각 기사는 다음과 같은 구조로 되어 있음. 붉은색 부분만 추출하고자 함.
<dl class="list_item"> <dt><a href=" 감독 형식은 자진사퇴, 내용은 경질?</a></dt> <dd class="thumb"><a href=" src=" alt=""></a></dd> <dd class="desc"><a href=" 한화 이글스 감독이 자진사퇴했고, 한화 구단은 사의를 수용하며 이상군 투수코치를 감독대행에 임명했다.김 감독은 지난 21일 대전 삼성 라이온즈전을 마..</a></dd> <dd class="date_author"> <span class="date"> (수)</span> | <span class="author"> 스포츠조선=박재호 기자 </span> </dd> </dl>
5
Ruby script를 바깥쪽부터 작성함 사용자로부터 시작 날짜와 끝 날짜를 입력받아, 각 날짜의 조선일보 스포츠 웹페이지를 읽어옴. require 'date' require 'net/http' begin_date = Date.new(ARGV[0].to_i, ARGV[1].to_i, ARGV[2].to_i) end_date = Date.new(ARGV[3].to_i, ARGV[4].to_i, ARGV[5].to_i) Net::HTTP.start("news.chosun.com") do |http| #조선일보 홈페이지에 접속 begin_date.upto(end_date) do |date| #시작 날짜부터 끝 날짜까지 d = date.to_s.gsub("-","") #날짜를 문자열로: url = "/svc/list_in/list_title.html?catid=G1&indate=#{d}" #해당 날짜의 스포츠 기사 웹 주소 e = find_end_page(http, url, 1) #해당 날짜의 스포츠 기사의 페이지 수 알아냄 (1..e).each do |i| #1페이지부터 끝 페이지까지 search(http, url+"&pn=#{i}") #search 함수 호출 end
6
find_end_page 함수 @end_pattern = %r|<li><a style="text-decoration:none;cursor:default" class="current">[0-9]+</a></li><li><a style="text-decoration:none;cursor:default">| #마지막 페이지의 특징을 정규표현으로 포착함. def find_end_page(http, url, n) #스포츠 기사가 몇 페이지까지 있는지 알아내는 함수 str = http.get(url+"&pn=#{n}").body #n번째 페이지를 읽어옴 if not str #마지막 페이지가 아니면 find_end_page(http, url, n+1) #find_end_page 함수 재귀 호출 else #마지막 페이지이면 return n #n을 반환하고 함수 종료 end
7
search 함수 @pattern = %r|<dt><a href=" def search(http, url) puts url #url 출력 str = http.get(url).body #url의 웹 문서를 불러옴 do |date, title| #웹 문서에서 정규표현(pattern)을 찾음. #괄호 친 두 부분을 date, title이라 지칭 print date, "\t", title, "\n" #date와 title 출력 end
8
위의 코드의 문제 해당 날짜의 스포츠 웹페이지가 몇 페이지까지 있는지 알아내는 함수(find_end_page)에서도 각 웹페이지의 문서를 읽어오고 각 웹문서를 읽어와서 제목을 추출하는 함수(search)에서도 각 웹페이지의 문서를 읽어오게 되어 있어서 같은 일을 2번 반복하는 꼴이 됨. 페이지 수만큼 반복하는 iterative algorithm을 적용하는 셈. 각 웹페이지 문서를 1번만 읽어오면서 과제를 수행하기 위해서는 recursive algorithm이 필요함. 날짜와 일련번호를 가지고 url을 만드는 일은 search 함수에게 맡기는 게 나음. (그러면 calling code가 더 깔끔해짐.)
9
recursive algorithm을 적용한 calling code
Net::HTTP.start("news.chosun.com") do |http| begin_date.upto(end_date) do |date| search(http, date, 1) #첫째 페이지에 대해 search 함수 호출 end
10
search 함수 def search(http, date, n)
d = date.to_s.gsub("-","") #날짜를 문자열로: url = "/svc/list_in/list.html?catid=G1&indate=#{d}&pn=#{n}" puts url #url 출력 str = http.get(url).body do |date, title| print date, "\t", title, "\n" #date와 title 출력 end search(http, date, n+1) if not str #마지막 페이지가 아니면 n을 1 증가시켜 함수 재귀 호출
11
동아일보 동아일보 홈페이지, 스포츠, 최신기사, 날짜별로 들어가 보면, 전반적인 구조는 조선일보와 비슷함.
한 페이지에 20개의 기사씩 제시되고 url에 첫 기사의 일련번호(1,21,41,...)와 날짜가 포함됨. 조선일보와 비슷하게 search 함수를 재귀호출하되 이 함수의 parameter에 일련번호도 포함시켜야 함.
12
동아일보용 calling 코드 @pattern = %r|<div class='articleList'><div class='rightList'><a href=' class='tit'>(.+?)</span>| @end_pattern = %r|</a><strong>[0-9]+</strong><a href='\?p=none\&prod=news\&ymd=[0-9]{8}\&m=' class='right'>| Net::HTTP.start("news.donga.com") do |http| begin_date.upto(end_date) do |date| search(http, date, 1) #search 함수 호출 end
13
동아일보용 search 함수 def search(http, date, n)
d = date.to_s.gsub("-","") #날짜를 문자열로: url = "/List/Sports/?p=#{n}&prod=news&ymd=#{d}&m=" puts url #url 출력 str = http.get(url).body #url의 웹 문서를 불러옴 do |date, title| print date, "\t", title, "\n" #date와 title 출력 end search(http, date, n+20) if not str #마지막 페이지가 아니면 search 함수 재귀 호출
Similar presentations