Python版 ぴくぴくダウンローダーを作成している夢を見た
6月 27, 2014 — 10:50

完全オープンソースにするか悩みどころですが取りあえずモチベーション維持のためにもちょくちょくソースコードを公開していこうと思います。

単純にダウンロードするなら簡単なんですが、アレもできてコレもできてとなると中々大変なんですよね(汗

GUIを作るのがかなりしんどいので取りあえず、いつも通りCUI版を作ってGUIを上からかぶせる感じで行こうと思います。
実はTideSDKを使う予定だったけど暗礁に乗り上げてます。誰かアドバイスをください。
※ 毎回GUI後付でやってるけどうまく行っている気がしない・・・

今回の目標
・Pythonを触ったことがない人でも処理をおおまかに理解できるよう書く(そもそも自分がPythonド素人)
・Java版の時みたいに糞長いソースコードを力押しで書かない(今後の保守性を再優先)
・Perl版の時みたいに正規表現のスクランブルにしない(あれは黒歴史)

# vi PixivBrowser.py

# -*- coding:utf-8 -*-
#################################################################
#
# Pixivのブラウザエミュレータ
#
#  Pixivの接続情報を保持する
#  UA設定やProxy設定を組み込むかもしれない
# 
# 【制作開始日時】 2014/06/25
# 【   製作者   】 orbit
# 【  動作環境  】 Python 2.7 (Win, Mac, Linuxで動くのが理想)
#
# 【   更新日   】
#    2014/06/25    ログイン処理に関する部分を作成 
#                  seleniumを使うか悩んだがPixivへの負荷を考慮
#
#    2014/06/27    認証を行うメソッドの名前を変更
#
#################################################################
import mechanize

# Pixivのブラウザエミュレータを担当するクラス
class PixivBrowser(object):
  def __init__(self):

    # Pixivのログインページ
    self.loginurl = 'https://www.secure.pixiv.net/login.php'
    # Pixivのユーザーページ
    self.userpage = 'http://www.pixiv.net/mypage.php'

    # ブラウザエミュレータのインスタンス生成
    self.browser = mechanize.Browser()

    # 当然検索エンジンよけを無視
    self.browser.set_handle_robots(False)

  # Pixivの認証を行う
  def auth(self, username, password):
    # ユーザ情報
    self.username = username # ユーザー名
    self.password = password # パスワード

    # ログインページを開く
    self.browser.open(self.loginurl)
    
    # ユーザ名とパスワードを指定してログイン
    self.browser.select_form(nr=1)
    self.browser["pixiv_id"] = self.username
    self.browser[  "pass"  ] = self.password
    self.browser.submit()

    # ログインに成功した確認する
    res = self.browser.response() # レスポンスを受け取る
    url = res.geturl()            # 現在のURLを取得する

    # ログイン後にユーザページにいないのはログイン失敗
    if(url != self.userpage):
      # ログインに失敗した場合はどうしようもないので例外を投げる
      raise PixivBrowserException("login failed. please check you are account.")

    # ログインページのHTMLを取得
    html = self.browser.response().read()

    # 問題なくログインできたらドヤ顔でログインページのHTMLを返す
    return html

  # ブラウザエミュレータを返す
  def getBrowser(self):
    return self.browser

# PixivBrowserのプログラム内で処理継続が不能になったら呼ばれる例外クラス
class PixivBrowserException(Exception):
  def __init__(self, str):
    self.str = str   # strはraise文から受け取る引数

  def __str__(self): # エラーメッセージ
    return '%s' % (self.str)

## 以下、デバッグ用の処理 ##
if __name__ == '__main__':
  pb = PixivBrowser()
  pb.auth('**************', '**************')

# vi PixivSearch.py

# -*- coding:utf-8 -*-
#################################################################
#
# Pixivの絵画(絵・漫画)を検索・ページングするプログラム
#
#  検索で並び順の変更に対応するかもしれない
# 
# 【制作開始日時】 2014/06/27
# 【   製作者   】 orbit
# 【  動作環境  】 Python 2.7 (Win, Mac, Linuxで動くのが理想)
#
# 【   更新日   】
#    2014/06/27    検索とページングを行う部分を作成
#                  絵・漫画・小説の他にうごくイラストをサポート
#
#################################################################

# Pixivの絵画(絵・漫画)を検索するクラス
class PixivSearch(object):
  def __init__(self, browser):
    ## ページ情報 ##
    # Pixivのユーザーページ
    self.userpage = 'http://www.pixiv.net/mypage.php'
    # 検索ページベース
    self.pixibass = 'http://www.pixiv.net'
    
    # 並び順
    self.pagesort = '&order=date_d'
    
    # ページ番号
    self.pagenumb = 1;
    
    ##  ブラウザ  ##
    self.browser   = browser
  
  # 通常の検索(絵・漫画混在) 今回、仕様的に使うか微妙
  def search(self, keyword):
    # 検索キーワード
    self.keyword = keyword
    
    # 検索パラメータをつける
    self.searcurl = self.pixibass + '/search.php?word=' + keyword + self.pagesort + '&p='
    
    # ページ番号を付加して検索ページを開く
    self.browser.open(self.searcurl + str(self.pagenumb))
    
    # 検索結果ページのHTMLを取得
    html = self.browser.response().read()
    
    # 検索結果ページのHTMLを返す
    return html
  
  # 絵の検索
  def searchImage(self, keyword):
    # 検索キーワード
    self.keyword = keyword
    
    # 検索パラメータをつける
    self.searcurl = self.pixibass + '/search.php?word=' + keyword + '&manga=0' + self.pagesort + '&p='
    
    # ページ番号を付加して検索ページを開く
    self.browser.open(self.searcurl + str(self.pagenumb))
    
    # 検索結果ページのHTMLを取得
    html = self.browser.response().read()
    
    # 検索結果ページのHTMLを返す
    return html
  
  # 漫画の検索
  def searchComic(self, keyword):
    # 検索キーワード
    self.keyword = keyword
    
    # 検索パラメータをつける
    self.searcurl = self.pixibass + '/search.php?word=' + keyword + '&manga=1' + self.pagesort + '&p='
    
    # ページ番号を付加して検索ページを開く
    self.browser.open(self.searcurl + str(self.pagenumb))
    
    # 検索結果ページのHTMLを取得
    html = self.browser.response().read()
    
    # 検索結果ページのHTMLを返す
    return html
  
  # うごくイラストの検索
  def searchUgoku(self, keyword):
    # 検索キーワード
    self.keyword = keyword
    
    # 検索パラメータをつける
    self.searcurl = self.pixibass + '/search.php?word=' + keyword + '&type=ugoira' + self.pagesort + '&p='
    
    # ページ番号を付加して検索ページを開く
    self.browser.open(self.searcurl + str(self.pagenumb))
    
    # 検索結果ページのHTMLを取得
    html = self.browser.response().read()
    
    # 検索結果ページのHTMLを返す
    return html
  
  # 小説の検索
  def searchNovel(self, keyword):
    # 検索キーワード
    self.keyword = keyword
    
    # 検索パラメータをつける
    self.searcurl = self.pixibass + '/novel/search.php?s_mode=s_tag&word=' + keyword + self.pagesort + '&p='
    
    # ページ番号を付加して検索ページを開く
    self.browser.open(self.searcurl + str(self.pagenumb))
    
    # 検索結果ページのHTMLを取得
    html = self.browser.response().read()
    
    # 検索結果ページのHTMLを返す
    return html
  
  # ページ番号を前進
  def nextPage(self):
    # ページ番号をインクリメントする
    self.pagenumb = self.pagenumb + 1
    
    # 次のページ番号を返す
    return self.pagenumb
  
  # ページ番号を後進 今回、仕様的に使うか微妙
  def backPage(self):
    # ページ番号をデクリメントする
    self.pagenumb = self.pagenumb - 1
    
    # 次のページ番号を返す
    return self.pagenumb
  
  # 現在のページ番号を得る
  def getPage(self):
    # 現在のページ番号を返す
    return self.pagenumb
  
  # 現在のページ番号を変更する
  def setPage(self, page):
    # ページ番号を書き換える
    self.pagenumb = page
    
    # 現在のページ番号を返す
    return self.pagenumb

# PixivSearchのプログラム内で処理継続が不能になったら呼ばれる例外クラス
class PixivSearchException(Exception):
  def __init__(self, str):
    self.str = str   # strはraise文から受け取る引数

  def __str__(self): # エラーメッセージ
    return '%s' % (self.str)

## 以下、デバッグ用の処理 ##
if __name__ == '__main__':
  from PixivBrowser import *

  pb = PixivBrowser()
  pb.auth('**************', '**************')
  browser = pb.getBrowser()

  ps = PixivSearch(browser)
  #print ps.search("ミク")
  #print ps.searchImage("ミク")
  #print ps.searchComic("ミク")
  #print ps.searchUgoku("ミク")
  #print ps.searchNovel("ミク")
  ps.setPage(100)
  ps.nextPage()
  print ps.search("ミク")

進捗状態
次は検索結果のHTMLを構文解析するクラスと作品ごと情報を保持するクラスを作成する予定
ID検索の部分に入るまでもう少し時間がかかりそうな予感

Comments:
  • sky

    僕はVB6.0を少しかじってる程度ですけど分かりやすいですね。
    宣言とか細かい事は分かりませんけど、流れは凄く参考になります。
    思ったよりも難しいことをしてなさそうなのが驚きです。

    9月 21, 2014 — 7:55
  • コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

    (Spamcheck Enabled)

    日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)