본문 바로가기

Robotics/Software Tech.

python을 이용한 google 검색 데이터 수집


글쎄.. 잘은 모르겠다. 이렇게 접근하고 있는 것이 과연 적절한 방법인지.
어떤 로봇이든 agent든.. 사람이 아닌 기계가 어떤 객체를 이해한다는 것은 무엇을 의미하는가. 영상이든 음성이든 인식을 한다는 것과 이해를 한다는 것은 다르다. 영상을 인식한다는 것은 영상에 나타난 어떤 객체의 특징을 보고 이 객체의 이름이 무엇인지를 기존에 학습한 데이터에서 분류를 하는 것이다. 학습하지 않은것은 당연히 무엇인지 알 수 없다.

지금 하고자 하는 것은 인식의 문제가 아니라, 인식이 이루어지고 난뒤에 그 객체가 가지는 특성, 개념들을 우리가 임의로 정의하지 않고 얻을 수 있는 방법이 무엇이 있을까를 고민하다가, 매일 접하는 웹에서 데이터를 일단 얻어보기로 했다. 아무래도, 객체의 특성이나 객체들이 개념들이 formal하게 어떤 구조를 가지고 잘 표현되어 있지는 않겠지만, 어느정도 filtering해준다면 어느정도 우리가 봤을때가 acceptable하게 표현될 수 있지 않을까 한다.

우선 코드는 python으로 구현되었으며 google로부터 던져진 query에 대해 response가 온 페이지를 parsing하여 결과 url을 추출하고, 다시 그 url을 접속하여 해당 페이지에서 tag를 제외한 모든 text를 파일로 저장할 것이다. 일단 객체라고 google image search engine에서 데이터를 얻으면 좀더 query 단어의 ambiguity를 줄일 수 있지 않을까 생각했지만, 실험해서 살펴보니 크게 차이가 없는것 같았다. 왜냐하면 'water'라고 해서 'drink'라는 단어가 꼭 결과로 나오리라는 보장이 없기때문이다. 즉 결론적으로 water로 검색한 결과에서 drink라는 결과를 얻기를 원한다면 우리는 drink와 연관될 수 있는 다른 단어들도 query로 같이 넘겨줘야 할지도 모르겠다. 그래야 좀더 drink가 나오기를 기대할 수 있는 어떤 기대값이 높아질테니 말이다.

아래는 google.com에서 keyword로 query를 던져서 결과페이지에서 url들을 extract해오는 클래스이다. mechanize library를 이용하여 데이터를 얻어왔다. (코드중간에 html tag가 들어가버리니 code syntax highlight가 좀 잘 안된다. 그래서 그냥 올린다.)



#-*- coding:utf-8 -*-
# original web data collecting class using Google Search Engine
# Byunghun Hwang <elecun2@gmail.com>

import mechanize
import os
import time

class collector:
    def __init__(self):
        self._browser = mechanize.Browser(factory=mechanize.RobustFactory())
        self._browser.set_handle_equiv(True)
        self._browser.set_handle_redirect(True)
        self._browser.set_handle_referer(True)
        self._browser.set_handle_robots(False)
        self._browser.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
        self._browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1')]

    def goNext(self, response):
        temp_index = response.rfind('Next')
        if temp_index < 0:
            return False

        buf = response[:temp_index]
        start_index = buf.rfind('href="')
        buf = response[start_index+len('href="'):temp_index]
        nextpage = 'http://www.google.com'+buf[0:buf.find('\"')]
        nextpage = nextpage.replace('amp;','')
        self._browser.open(nextpage)
        response = self._browser.response().read()
        return response

    def search(self, workingPath, keyword, nmax):
        orgPath = workingPath + '\\' + keyword + '\\org\\'

        #create folder
        if os.path.exists(orgPath)==False:
            os.mkdir(orgPath)

        #검색
        self._browser.open('http://www.google.com/search?hl=en&q='+keyword+'&lr=lang_en')
        response = self._browser.response().read()

        #결과저장
        orgFile = file(orgPath + keyword + '.txt','w')
        orgFile.write(response)
        orgFile.close()

        #url list
        urllist = []
        urllist = self.getURLs(response, urllist, nmax)

        #max가 될때까지 url 추출.
        while len(urllist)<nmax:
            response = self.gotoNextSearch(orgPath, keyword, response)
            if response == '':
                break
            self.getURLs(response, urllist, nmax)

        return urllist

    def gotoNextSearch(self, directory, keyword, response):
        temp_index = response.rfind('Next')
        if temp_index < 0:
            return ''

        #next page 주소 추출
        buf = response[:temp_index]
        start_index = buf.rfind('href="')
        buf = response[start_index+len('href="'):temp_index]
        nextPage = 'http://www.google.com' + buf[0:buf.find('"')]
        nextPage = nextPage.replace('amp;','')

        #go to next page
        self._browser.open(nextPage)
        response = self._browser.response().read()
        
        return response

    #검색결과에서 result URL을 추출한다. <h3 class="r"> tag뒤에 나오는 url을 가져온다.
    def getURLs(self, response, urllist, nmax):
        start_index = 0
        while  start_index > -1:
            start_index = response.find('<h3 class="r">', start_index)

            if start_index <0:
                start_index = 0
                break
            
            start_index = response.find('<a href="',start_index)+len('<a href="')
            end_index = response.find('"',start_index+1)
            url = str(response[start_index:end_index])

            urllist.append(url)
            nURL = len(urllist)
            print '[%3.1f%%(%d/%d)] : '%((float(nURL)/float(nmax)*100.0),nURL,nmax)+url
            if nURL==nmax:
                break

        return urllist 

클래스에서 search라는 함수를 호출하면 된다. keyword와 결과 url 몇개를 가져올것인지를 인자로 주면 된다.