baobao
4/28/2013 - 10:13 AM

Naverまとめ画像を一括ダウンロードするPythonスクリプト

Naverまとめ画像を一括ダウンロードするPythonスクリプト

# -*- coding: utf-8 -*-

'''
ネイバーまとめから画像をダウンロードするスクリプトpython版
MatomeLinkCollector
画像のリンク先が外部サイトの場合は未対応。

@Author Shunsuke Ohba
2013.04.28
'''


import sys	# モジュール属性 argv を取得するため
import urllib
import re
from HTMLParser import HTMLParser
import os.path
import os
import datetime # datetimeモジュールのインポート
import locale
#mode
DEBUG_MODE = False

#画像を保存するローカルディレクトリパスを指定する
BASE_PATH = "/Users/USER/Desktop/"

#リンクを取得する正規表現
pattern = re.compile(r'<a href="(\S+?)">(.+?)</a>')
CHECK_PATH = "http://imgcc.naver.jp/kaze/mission/USER/"

argvs = sys.argv  # コマンドライン引数を格納したリストの取得
argc = len(argvs)

d = datetime.datetime.today()
date = d.strftime("img%Y-%m-%d-%H-%M-%S")


def start(checkUrl, page):
    
    current = 1
    imgList = []
    oritinalUrl = checkUrl
    
    #クエリが存在する場合はそのページのみ取得する
    if checkUrl.find("?page=") >= 0 :
        html = getHtmlSource(checkUrl)
        pathList = getPathList(html)
        for link in getRealImagePath(pathList):
            imgList.append(link)
        pritnImage(imgList)
        return
    
    
    #引数は数値にキャストしないと無限ループする
    while current <= int(page):
        if current > 1:
            #2ページ目以降はクエリ付与
            query = "?page=%s" % current
            url = oritinalUrl + query
        else:
            url = oritinalUrl
#        print checkUrl
        current += 1
        html = getHtmlSource(url)
        pathList = getPathList(html)
        
        for link in getRealImagePath(pathList):
            imgList.append(link)

        current += 1
    pritnImage(imgList)


class out_link_parser(HTMLParser):
	def __init__(self):
		HTMLParser.__init__(self)
		self.links = {}
		self.linkurl = ''

	#aタグのみ処理を行い、href属性の内容をlinkurlに格納
	def handle_starttag(self, tag, attrs):
		if tag == 'a':
			attrs = dict(attrs)
		if 'href' in attrs:
			self.linkurl = attrs['href']

  # linkurlに値が入っている場合のみ、(つまりAタグの場合)
  # urlをキー:アンカーテキストをバリューとしてディクショナリに追加
	def handle_data(self, data):
		if self.linkurl:
			self.links[self.linkurl] = data
			self.linkurl = ''


def getPathList(html):
	list = []
	parser = out_link_parser()
	# 日本語があるのでUnicodeに変換
        
	try:
		parser.feed(html.decode('utf-8'))
		parser.close()
	except:
		print "error::getPathList"
		return list
	url = ""
	for k, v in parser.links.items():
		k_str = k.encode('utf-8')

		# アンカーテキストの先頭/末尾のスペースや改行などを除去
		v_str = re.sub('^[ \n\r\t]+|[ \n\r\t]+$', '', v).encode('utf_8')
 
		
		# 現状相対リンクに対応していない
		if re.match('^/', k_str):
			pass
			# 相対パスやアンカーの場合、ルートのURLを先頭に付与
			#url = "%s: %s" % (re.sub('^/', target, k_str), v_str)
			#list.append(url)
			#print url
			#print "%s: %s" % (re.sub('^/', target, k_str), v_str)
		#elif re.match('^#', k_str):
			#print "%s: %s" % (re.sub('^#', target + '#', k_str), v_str)
		else:
			#print "%s: %s" % (k_str, v_str)
			
			#URLとtitleのセット
			#url = "%s: %s" % (k_str, v_str)

			url = "%s" % (k_str)
			list.append(url)
	return list



#HTMLソースを取得
def getHtmlSource(url):
	try:
		#エラーを発生させるため0除算
		filehandle = urllib.urlopen(url)
		html = filehandle.read()
		filehandle.close()
		return html
	except:
		if DEBUG_MODE:
			print 'エラー発生'
        return ""

#本画のURLを取得する
def getRealImagePath(linkList):
    result = []
    for link in linkList:
        #もう一階層潜る
        #print link
        html = getHtmlSource(link)

        if html != "":
            pathList = getPathList(html)
            path = checkCorrectPath(pathList)
            #print path
            if path != "" :
                #print path
                result.append(path)
    return result

def pritnImage(array):
    print "<html><head></head><body>"
    
    for link in array:
        #画像をローカルにダウンロード
        downloadImage(link)
        
        print "<a href=\"#\" onClick=\"window.clipboardData.setData('text',\'" + link + "\')\"><img src=\""
        print link
        #p output = link[7, link.length];
        print "\" width=\"120\"/></a>"
        print "<textarea rows=\"6\" cols=\"5\">"+link+"</textarea>"
    print "</body></html>"


#本画が存在するリンクを返す
def checkCorrectPath(list):
	for url in list:
		if url.find(CHECK_PATH) >= 0:
			return url
	return ""

# ローカルに画像を保存する
def downloadImage(url):
	img = urllib.urlopen(url)
	dir = BASE_PATH + date
	if os.path.exists(dir) == False:
		os.mkdir(dir)
	path = dir + "/" + os.path.basename(url)
	localfile = open(path, 'wb')
	localfile.write(img.read())
	img.close()
	localfile.close()


#argvs[0]は自分のファイル名が来る
#第2引数は捜査するページ数
start(argvs[1], argvs[2])