처음에 이것을 풀기 위해 약간의 테스트를 했었는데, 인코딩 때문에 상당히 애를 먹었다.
한국 대부분의 html 파일들은 utf-8 로 인코딩이 되어 있다. 그러나 파이썬에서는 'mbcs' 로 인코딩하여 출력을 해준다. 이로 인해 페이지 소스와 출력물이 어긋났다.
urllib 모듈을 임포트 하여 print urllib.urlopen('http://bluekyu.textcube.com/').read() 을 하면 소스가 잘 나온다. 하지만 내가 이 문제를 풀기 위해 소스를 한 줄씩 읽기 위해 for line in urllib.urlopen('http://bluekyu.textcube.com/') 으로 하여 print line, 을 했더니 '§' 부분이 '짱' 으로 표시 되는 것이다. ㅡㅡ;;;;
처음에는 읽기에 문제가 있는지 확인 할려고 파이썬 3.1 까지 깔아서 삽질을 했지만 결국 못 알아내고 한국 파이썬 모임에 물어 보니 인코딩 문제라고 했다.
>>> print '\xc2\xaf'.decode('cp949').encode('utf-8')
짱
위 코드에서 \xc2\xaf 는 utf-8 코드로 '§' 을 의미 한다. 그러나 파이썬에서 저 코드를 cp949(mbcs) 로 받아 들이면 유니코드로 '짱' 이라는 의미가 된다.
어쨌든 인코딩 때문에 애를 먹고, 어차피 파일로 저장하므로 인코딩에 신경 쓰지 않고 코딩을 했다.
import os, urllib, urlparse, re def regu(urlstring) : if urlstring[-1] == '/' : return urlstring[:-1] return urlstring def url_Add(add_url) : global urllist if add_url not in urllist : urllist.append(add_url) def makedir(link, flist) : if len(flist) > 0 : k = flist.pop(0) if not (os.path.exists(link + '/' + k)) : os.mkdir(link + '/' + k) makedir(link + '/' + k, flist) urllist = [regu(raw_input('Input URL : '))] os.mkdir('./htmlpage') for url in urllist : flink = url.split(urllist[0])[-1] makedir('./htmlpage/', flink.split('.')[0].split('/')[1:]) if url == urllist[0] : f = open('./htmlpage/' + url.split('http://')[-1] + '.html', 'w') else : f = open('./htmlpage' + flink.split('.')[-2] + '/' + flink.split('/')[-1], 'w') for line in urllib.urlopen(url) : f.write(line) url_2 = re.search(r'href(\s?)=(\s?)"(.*?).html"', line) or re.search(r'href(\s?)=(\s?)"(.*?).htm"', line) if url_2 : addurl = regu(url_2.group().split('"')[-2]) if re.search('http:', addurl) : if re.search(urllist[0], addurl) : url_Add(addurl) else : url_Add(urllist[0] + '/' + addurl)상당히 긴 코드인데, 이거 푸느라 시간이 상당히 많이 걸렸다.
이 문제를 푸는 방법은 html 의 소스에서 <a> 태그를 이용하는 방법이다. 페이지 링크는 <a> 태그에 href 속성에 걸려 있으므로 href 에 걸려 있는 링크를 정규식으로 추출하고 저장했다.
문제를 풀다보니 처음에 입력한 url 의 페이지에 있는 링크 외에도 링크가 연결된 페이지에 존재하는 링크의 페이지도 저장을 했다. 그리고 여기에다가 디렉토리 구조도 같은 구조로 만들었다.
ps. 잘 되는 줄 알았는데, 약간 작동이 잘 안되는 것 같다.
댓글 없음:
댓글 쓰기