본문 바로가기

IT/Python

파이썬 웹프로그래밍 - 이미지 다운로드 (urllib2, httplib) 소스

/* 
written by kaspy (kaspyx@gmail.com)
*/ 

 파이썬은 코드가 간단하면서 어렵지않고 유용한 기능이 많다. 이번 포스팅에서는 파이썬에서 특정 웹사이트에 접속하여 이미지만 추출해서 다운로드하는 코드를 소개하겠다.

1. urllib2 모듈 예제

 아래 코드는 네이버 웹사이트에 접속해서 그림 (img tag) URL을 보여주는 파이썬 코드이다.


  1. #!/usr/bin/env python
  2. from urllib2 import urlopen
  3. from HTMLParser import HTMLParser
  4.  
  5. class ImageParser(HTMLParser):
  6.   def handle_starttag(self, tag, attrs):
  7.     if tag != 'img':
  8.       return
  9.     if not hasattr(self, 'result'):
  10.       self.result = []
  11.     for name, value in attrs:
  12.       if name == 'src':
  13.         self.result.append(value)
  14.  
  15. def parseImage(data):
  16.   parser = ImageParser()
  17.   parser.feed(data)
  18.   dataSet = set(for x in parser.result)
  19.   imgurl = '\n'.join( sorted(dataSet) )
  20.   print imgurl
  21.  
  22. def main():
  23.   url = "http://www.naver.com"
  24.   f = urlopen(url)
  25.   charset = f.info().getparam('charset')
  26.   data = f.read().decode(charset)
  27.   f.close()
  28.   print "\n>>>>> Fetch Images from", url
  29.   parseImage(data)
  30.  
  31. if __name__ == '__main__':
  32.   main()


5,6번 라인, HTMLParser 클래스를 사용할때는 이렇게 상속받는 클래스를 정의하고 필요한 내용을 오버라이드 하는 형태 구현되며 <img>라는 태그를 찾기위하여 handle_starttag() 함수를 오버라드이드 하였다. 11번 라인 for 루프가 있는데, <img src> 속성을 찾으면 속성값을 self.result 리스트에 추가하는 내용이다. 15번 라인 parseImage() 함수에 의해 <img> 태그 리스트를 출력해주는데, 17번 라인의 feed함수는 파싱하고 그결과를 parser.result에 추가해주는 내용이다.(ImageParser내부 객체) 특히 25번 라인, 사이트에서 가져온 데이터는 인코딩 되어있는데 이를 반드시 decode 해줘서 파싱해야함을 기억해야한다.


아래는 실행 결과 화면이다.



2. httplib 모듈 예제

 httplib 모듈은 urllib2 모듈의 상위 모듈로 urllib2도 이 모듈을 상속받아서 구현됬다고 한다. 이모듈은 urllib2 보다 좀더 저수준의 세밀한 기능이 필요할때 사용된다고 한다. 모듈을 활용하여 이번엔 결과 리스트에 존재하는 그림 파일들을 다운로드 하는 코드를 설명하도록 하겠다.

 아래는 네이버 웹사이트에 접속하여 그림파일들을 DOWNLOAD 디렉토리에 다운로드하는 파이썬 코드이다.


  1. #!/usr/bin/env python
  2.  
  3. import httplib
  4. from urlparse import urljoin, urlunparse
  5. from urllib import urlretrieve
  6. from HTMLParser import HTMLParser
  7. import os
  8.  
  9. class ImageParser(HTMLParser):
  10.   def handle_starttag(self, tag, attrs):
  11.     if tag != 'img':
  12.       return
  13.     if not hasattr(self, 'result'):
  14.       self.result = []
  15.     for name, value in attrs:
  16.       if name == 'src':
  17.         self.result.append(value)
  18.  
  19. def downloadImage(srcUrl, data):
  20.   if not os.path.exists('DOWNLOAD'):
  21.     os.makedirs('DOWNLOAD')
  22.  
  23.   parser = ImageParser()
  24.   parser.feed(data)
  25.   resultSet = set(for x in parser.result)
  26.  
  27.   for x in sorted(resultSet):
  28.     src = urljoin(srcUrl,x)
  29.     basename = os.path.basename(src)
  30.     targetFile = os.path.join('DOWNLOAD', basename)
  31.  
  32.     print "Downloading,..,", src
  33.     urlretrieve(src, targetFile)
  34.  
  35. def main():
  36.   host = "www.naver.com"
  37.  
  38.   conn = httplib.HTTPConnection(host)
  39.   conn.request("GET",'')
  40.   resp = conn.getresponse()
  41.  
  42.   charset = resp.msg.getparam('charset')
  43.   data = resp.read().decode(charset)
  44.   conn.close()
  45.  
  46.   print "\n>>>>>> Download Images from ", host
  47.   url = urlunparse(('http',host, '','','',''))
  48.   downloadImage(url,data)
  49.  
  50. if __name__ == '__main__':
  51.   main()


 7번 라인은 os 모듈은 21번 라인 makedirs() 함수를 실행하기위해 import 하였다. 24,25번 라인은 feed()함수를 사용하여 HTML 문장을 파싱하여 그결과를 바로 parser.result 리스트에 추가하고 이를 resultSet (set 자료 타입) 에 저장하는 코드는 다시한번 상기하기 위해 설명하였다. 

 for 루프문 안에 28번 라인은 다운로드 하기위한 URL과 타겟 파일명을 지정하는데, URL을 지정할때 urljoin() 함수를 사용한다. 이함수는 baseURL과 파일명을 합쳐서 완전한 URL을 리턴하는 함수이다. 

 이미지를 다운로드 하기위해 33번 라인 urlretrieve 함수를 사용하고 있다. 첫번째 인자 src의 url에 접속하여 두번째 인자 targetFile로 파일로 생성해준다. 38번 라인의 HTTPConnection 함수는 인자가 url이 아니라 host:port 임을 기억해야한다. port가 지정되지 않으면 default로 80 (http포트)로 지정된다. 47번 라인의 urlunparse 함수는 URL 요소 6개를 튜플로 받아서 이를 조립하여 완성된 URL을 리턴하는 함수로써 앞서 설명했던 urlparse() 함수와 반대되는 기능을 한다.



* 관련된 내부 링크 

파이썬 웹프로그래밍 - 웹클라이언트 urlparse 예제

파이썬 웹표준 라이브러리 소개 및 변경사항

* 참고 자료

django로 배우는 쉽고 빠른 파이썬 웹프로그래밍