Jリーグの試合結果を分析する。〜totoBIGを当てるために〜

BeautifulSoup

大したことはしません。Jリーグ公式サイトから試合結果をいただいて、コンピュータが扱いやすい形にしてあげるだけです。

スクレイピングには当然、BeautifulSoupを使います。

まずは公式サイトからどのようにスクレイピングしたら良いか探りましょう。

試合結果を公表しているページはここです。https://data.j-league.or.jp/SFMS01/

なにやら、色々と選択肢がありすぎて困りますが、いやはやこれは膨大なデータ量になりそうな予感

と思いきや、urlのパターンがわかれば簡単でした。

例えば、2016年のJ1の広島の全試合結果であれば、こうなります。

https://data.j-league.or.jp/SFMS01/search?competition_years=2016&competition_frame_ids=1&team_ids=10&home_away_select=0&tv_relay_station_name=

最後のテレビ何ちゃらは余計なので削除です。

  • competition_years=[年]
  • competiton_frame=[数字]
  • team_ids=[数字]
  • home_away_select=[数字]
  • これらが、検索のキーとなっているようです。

    jleague.py

    “`
    def game_data(year,competition,team_id,home_away):
    if year==” or year is None:
    a=”
    else:
    a=’competition_years=%s’ % year
    if competition==” or competition is None:
    b=”
    else:
    b=’&competition_frame_ids=%s’ % competition
    if team_id==” or team_id is None:
    c=”
    else:
    c=’&team_ids=%s’ % team_id
    d=’&home_away_select=%s’ % home_away
    url = ‘https://data.j-league.or.jp/SFMS01/search?’+a+b+c+d
    print(url)
    html = urllib.request.urlopen(url).read()
    soup = BeautifulSoup(html, "html5lib")
    “`
    soupを出すところまで書いてみました。
    とりあえず、game_data(year,competiton,team_id,home_away)で、検索結果のページを出すことができます。
    途中、空白やのNoneの条件を指定しているのは、チームを指定しない場合だとかで入力しない場合はごっそり消す必要があったからです。
    僕は初心者なので、ドンドンごり押してイキマス。

    データを綺麗にまとめる

    スープをゲットしたところで、テーブルの中の要素は使いにくい状態に置かれています。使いにくいというのは、コンピュータにとってであり、

    というわけで、soupの続きはこのようになります。
    “`
    game_data=[]
    search_table=soup.find(‘table’,{"class":"search-table"})
    line=search_table.find_all(‘tr’)
    for i in range(1,len(line)):
    year = line[i].find_all(‘td’)[0].text
    month = re.split(‘\(|\)|/|(|)|月|火|水|木|金|土|日|祝|・’,line[i].find_all(‘td’)[3].text)[0]
    day = re.split(‘\(|\)|/|(|)|月|火|水|木|金|土|日|祝|・’,line[i].find_all(‘td’)[3].text)[1]
    kohour=re.split(‘:’,line[i].find_all(‘td’)[4].text)[0].replace(‘\n’,”).replace(‘\t’,”)
    komin=re.split(‘:’,line[i].find_all(‘td’)[4].text)[1].replace(‘\n’,”).replace(‘\t’,”)
    home=line[i].find_all(‘td’)[5].text.replace(‘\n’,”).replace(‘\t’,”)
    away=line[i].find_all(‘td’)[7].text.replace(‘\n’,”).replace(‘\t’,”)
    score_home=re.split(‘-‘,line[i].find_all(‘td’)[6].text)[0].replace(‘\n’,”).replace(‘\t’,”)
    score_away=re.split(‘-‘,line[i].find_all(‘td’)[6].text)[1].replace(‘\n’,”).replace(‘\t’,”)
    stadium=line[i].find_all(‘td’)[8].text.replace(‘\n’,”).replace(‘\t’,”)
    game=(int(year),int(month),int(day),int(kohour),komin,home,away,score_home,score_away,stadium)
    game_data.append(game)
    return game_data
    “`
    search_tableというのは、もちろん検索結果ページでスクレイピングの対象となるテーブルです。
    次にlineは、そのテーブルの行になります。
    次のfor文 では、頭を除く全ての行に関して、試合結果のテキストを取得しています。
    例えば試合の日付は、○月○日(土)といったように、漢字やかっこが含まれているので、re.split() でまとめて分割しちゃいます。
    そのあとで、分割されたリストから月と日付にあたる部分を抜き出しています。

    所々replace() を使っているのは、\nや\tが発生するためです。なんでだろ?
    スコアは同様にハイフンを消しています。
    これで、綺麗にデータをまとめることができました。

    なぜスタジアムの名前も取得しているのかというと、後々にスタジアムの天気まで把握しようと考えているからです。

    結果

    “`
    game_data=game_data(2016,1,”,0)
    print(game_data)
    “`
    実行結果は、まぁすごい量の文字数になるので割愛しますが、次のようなフォーマットで出てきます。
    [(2016,02,27,16,04,’広島’,’川崎F’,0,1,Eスタ)]
    これでスタジアムのところをあとで気象庁から持ってきた当時の天気情報に差し替えたら完璧じゃないっすかね

    この得られたデータをどう使うかはあなた次第。

    例えば、今年の名古屋の勝ち点計算だって簡単にできちゃいます。
    “`
    def team_season(team,home,home_score,away,away_score,point):
    if team in home:
    print(home,home_score,away_score,away)
    if int(home_score)-int(away_score)<0:
    point+=0
    print(‘負け 勝ち点:%s’%str(point))
    elif int(home_score)-int(away_score)>0:
    point+=3
    print(‘勝ち 勝ち点:%s’%str(point))
    elif int(home_score)-int(away_score)==0:
    point+=1
    print(‘引分け 勝ち点:%s’%str(point))
    print(‘-‘*40)
    elif team in away:
    print(away,away_score,home_score,home)
    if int(away_score)-int(home_score)<0:
    point+=0
    print(‘負け 勝ち点:%s’%str(point))
    elif int(away_score)-int(home_score)>0:
    point+=3
    print(‘勝ち 勝ち点:%s’%str(point))
    elif int(away_score)-int(home_score)==0:
    point+=1
    print(‘引分け 勝ち点:%s’%str(point))
    print(‘-‘*40)
    else:
    pass

    def sample(team=’広島’,point=0):
    for i in range(len(game_data)):
    year =game_data[i][0]
    month =game_data[i][1]
    day =game_data[i][2]
    hour =game_data[i][3]
    minute =game_data[i][4]
    home =game_data[i][5]
    away =game_data[i][6]
    home_score =game_data[i][7]
    away_score =game_data[i][8]
    stadium =game_data[i][9]
    team_season(team,home,home_score,away,away_score,point)
    sample(team=’名古屋’)
    “`
    [python title=”Pythonコード”]
    —————————————-
    名古屋 1 1 磐田
    引分け 勝ち点:1
    —————————————-
    名古屋 0 3 神戸
    負け 勝ち点:0
    —————————————-
    名古屋 1 3 湘南
    負け 勝ち点:0
    —————————————-
    “`
    こんなふうに出てきます。あー腹たつ。
    というわけで、今はどのような条件で勝ちが多いかそれぞれのチームで検証しています。

    あとはスタジアムの天気情報ひっぱらなかん

  • AIプロジェクト3日目:文章中に現れた単語に対して知識をひけらかす機能

    とりあえず、持てる知識をどんどん出していってほしい。
    それがAIに学習させる醍醐味だと思うのです。

    とりあえず、プロトタイプとして、

    • 文章を区切り、sentenceにする
    • sentenceに対して、語彙リスト=voがの中の単語=キーが含まれているか確認する
    • 含まれていた単語に登録している知識=値からランダムに抽出
    • ランダムに抽出した知識をsentenceに対するコメントとして当てはめる。

    こんなものを作りたいと思う。

    文章を区切り、sentenceにする

    これは前回かそこらでやったけど、結局単語を細かく切っていくと、おかしなことになってしまうので一文ずつに切っていくのが良いとの結論に至った。

    [code lang=py]
    content='''
    長い文章・・・
    '''
    split_list1= '。|\n'
    sentence_list=re.split(split_list1,content)
    [/code]

    こんな感じで、元の文章を「改行」と「。」くらいで区切って、リストを作ってやる。

    語彙リストから参照する

    [code lang=py]
    vo={'単語1':['知識1','知識2'],'単語2':['知識1','知識2']}
    keys=list(vo.keys())
    comment_list={} #空の辞書={sentence:['知識1','知識2'],}
    for sentence in sentence_list:
    comment_list.update({sentence:[]}) #辞書に追加していく
    for key in keys:#それぞれのsentenceに対して
    if key in sentence:#語彙=キーが含まれているとき
    try:#語彙の知識=値をランダムに出してリストに登録
    comment_list[sentence].append(random.choice(vo[key]))
    except:#語彙はあるけど知識がないときはスルー
    pass
    else:#語彙がないときもスルー
    pass
    print(comment_list)
    [/code]

    こんなんで、多分行けるはず。

    試しに、
    sentence_list=[‘JVCケンウッドは、JVCブランドより、新シリーズ「SOLIDEGE(ソリデージ)」のハイレゾ対応ヘッドホンとして「HA-SD7」を発表’]

    で、試してみる。一応、語彙と知識はそれなりに貯めつつある。

    結果

    [code lang=text]
    {'JVCケンウッドは、JVCブランドより、新シリーズ「SOLIDEGE(ソリデージ)」のハイレゾ対応ヘッドホンとして「HA-SD7」を発表': ['神奈川県横浜市神奈川区(旧日本ビクター本社所在地)に本社を置く、映像機器・音響機器・無線機器メーカー', '音楽用CD(CD-DA)を超える音質の音楽データの総称']}
    [/code]

    おー、ちゃんとでてくれた。
    ちなみに、ヒットした語彙は、「JVC」と、「ハイレゾ」かな。
    これで、ひっちゃかめっちゃか自動で語彙を登録していき、ヒトの手でこつこつ知識を蓄えてあげていけば、、、成長するAIが作れるかもしれない・・・

    今日はここまで。

    次は、多分かなり進んでいると思う。

    【AIプロジェクト】2日目:リストに重複した単語を1つにまとめる方法

    #単語を抽出して語彙に記憶させる
    語彙をできるだけ多く記憶させるために、ひたすらリストにappend() していくのはいいけど、ゴミが増える。
    それぞれの語彙に対応する文章を割り出したい時に、その文章をもなんども引っ張ってくる恐れがあるから。

    そんな無駄をなくすために、今日はリストに重複した単語を消す方法を考える。

    リスト内の重複した単語を消去する

    サンプルリストを作成

    [code lang=py]
    nums=[1,2,3,4,5,2,3,4,5,6,7,7,7,3,2,3,4,3,4,2,2,2,4,5,6,3]
    [/code]

    とりあえず単語ではなくて数字にしてみる。適当に打ったので、何が何個含まれているのか、どれだけ重複しているのかわからない。

    まずは、すべての要素に対して何が何個含まれているのか調べよう

    重複した数字の個数を調べる

    [code lang=py]
    for num in nums: #numsリストにあるそれぞれのnumについて
    nums.count(num)
    [/code]

    リスト内に何個含まれているのか個数を調べるときは、count() を使う
    ##カウントされた数マイナス1回消去する

    次に、カウント数から1回引いた回数その数字を消せば良い

    [code lang=py]
    for num in nums:
    nums.count(num)
    for i in range(nums.count(num)-1): #カウントされた回数-1回の間
    nums.remove(num)
    [/code]

    これで、重複した数字の消去が完了した。結果は次の通り。

    [code lang=text]
    print(nums)

    [1, 6, 7, 2, 4, 5, 6, 3]
    [/code]

    【AIプロジェクト】1日目:文字列からキーワードを抽出するプログラムの作成

    突然AIを作ってみたくなった

    AIを作ってみたくなった。といっても、あらゆる情報から判断して何かができるようなたいそうなものは作れない。
    当面の目標は、価格.comの最新家電のニュースの感想を述べてくれるものを作りたいと思う。
    さしあたって必要になりそうな技術は、スクレイピング、これはある程度身についたので後回し。

    問題は、文字列の分析方法

    問題になってくるのは文字列をいかに読ませ、分析させ、適切な感想を返すことができるようにするかが肝となる。

    次に大事なのは、キャラクター性
    これも、機械的に言葉を返すようじゃ面白くないし、何かクセはあるけれども憎めない、そんなキャラクターが必要になってくる。
    あと、女子高生がいい。やっぱり。

    まずはキーワード抽出

    というのも、別のサイトで「ひとりガジェット速報(http://hitorigadget.wpblog.jp)」を運営しているけれども、いろいろとかなりグレーであるのと、
    やっぱり自分の言葉で述べることが必要だと感じたから。

    それはコピーコンテンツに対するSEO的な懸念と、物足りなさと、いろいろあるんだけど
    自分の言葉で表現できるなにかが必要だってことを強く感じ始めtから。

    そして、それでもやっぱり楽したい(クズ)

    じゃあ代わりに言葉を編んでくれる人を作ればいいじゃない。

    そんなわけで、とりあえず今日はキーワードをどうやって割り出すかを勉強した。

    split() では上手くいかない

    文字列を特定の文字列(,とか。とか)で分割する関数があるのは知っている。

    ただ、これは上手くいかない。

    [code lang=text]
    text='''
    新型CX-5のキーワードは「すべてのお客さまを笑顔にするSUV」。デザインは「洗練された力強さ」の表現を目指し、「魂動(こどう)」と呼ばれる同社のデザインコンセプトをより高い領域へ引き上げた。つややかさに精悍(せいかん)さを融合させた外観と、乗員の誰もが心地よさを感じる内装を作り上げることに挑戦したという。ボディーカラーには魂動デザインの造形を際立たせる新開発の「ソウルレッドクリスタルメタリック」を初採用した。ボディーサイズは全長4545×全幅1840×全高1690mmで、ホイールベースは2700mm。ラゲッジルーム容量は505リッター。 走行性能では、ドライバーのステアリング操作に応じてエンジンの駆動トルクを変化させることで車両の操縦性と安定性を高める「G-ベクタリング コントロール」を全車に標準装備したほか、静粛性や乗り心地を改善して同乗者の快適さも向上させた。また「マツダ・レーダー・クルーズ・コントロール」の追従速度を従来の30~100km/hから0~100km/hに拡大するなど、安全性能も見直した。 エンジンは、従来型と同じようにディーゼルが2.2リッター(SKYACTIV-D2.2)で、ガソリンが2リッター(SKYACTIV-G2.0)と2.5リッター(SKYACTIV-G2.5)となる。SKYACTIV-D2.2には、アクセル操作に対するクルマの反応をよりダイレクトにする「DE精密過給制御」のほか、ノック音を低減する「ナチュラル・サウンド・スムーザー」やノック音の発生そのものを抑制する「ナチュラル・サウンド・周波数コントロール」を採用し、走りの滑らかさと静かさを向上させた。JC08モード燃費は、SKYACTIV-D2.2:17.2~18.0km/リッター、SKYACTIV-G2.0:16.0km/リッター、SKYACTIV-G2.5:14.6~14.8km/リッター。
    '''
    text.split('。')
    [/code]

    出典:http://news.kakaku.com/prdnews/cd=kuruma/ctcd=7010/id=61358/
    splitでは、「。」の一つしか分割指定できないため、一文一文ずつしかリストにできない。
    そんなんでは、単語やらキーワード抽出やらできないではないか!

    とググって見ると、どうやらre.split() という正規表現があるらしい。


    http://www.lifewithpython.com/2014/08/python-use-multiple-separators-to-split-strings.html

    re.split()

    [code lang=py]
    import re
    text='''
    新型CX-5・・・・
    (中略)
    '''
    re.split('も|が|を|に|へ|と|より|から|で|や|の|は|、|。|!|?|!|「|」|(|',text)
    [/code]

    これで、「|」でわけた単語全てが分割要素となり、キーワードらしきものができた!

    [code lang=py]
    print(re.split('(中略)',text))

    ['\n新型CX-5', 'キーワード', '', 'すべて', 'お客さま', '笑顔', 'するSUV', '', 'デザイン', '', '洗練された力強さ', '', '表現', '目指し', '', '魂動', 'こどう', '', '', '呼ばれる同社', 'デザインコンセプト', '', '高い領域', '引き上げた', 'つ', '', 'かさ', '精悍', 'せいかん', 'さ', '融合させた外観', '', '乗員', '誰', '', '心地よさ', '感じる内装', '作り上げるこ', '', '挑戦した', 'いう', 'ボディーカラー', '', '魂動デザイン', '造形', '際立たせる新開発', '', 'ソウルレッドクリスタルメタリック', '', '初採用した', 'ボディーサイズ', '全長4545×全幅1840×全高1690mm', '', 'ホイールベース', '2700mm', 'ラゲッジルーム容量', '505リッター', '\n走行性能', '', '', 'ドライバー', 'ステアリング操作', '応じてエンジン', '駆動トルク', '変化させるこ', '', '車両', '操縦性', '安定性', '高める', 'G-ベクタリング コントロール', '', '全車', '標準装備したほか', '静粛性', '乗り心地', '改善して同乗者', '快適さ', '向上させた', 'また', 'マツダ・レーダー・クルーズ・コントロール', '', '追従速度', '従来', '30~100km/h', '0~100km/h', '拡大するなど', '安全性能', '見直した', '\nエンジン', '', '従来型', '同じよう', 'ディーゼル', '2.2リッター', 'SKYACTIV-D2.2', '', '', 'ガソリン', '2リッター', 'SKYACTIV-G2.0', '', '2.5リッター', 'SKYACTIV-G2.5', '', 'なる', 'SKYACTIV-D2.2', '', '', 'アクセル操作', '対するクルマ', '反応', '', 'ダイレクト', 'する', 'DE精密過給制御', '', 'ほか', 'ノック音', '低減する', 'ナチュラル・サウンド・スムーザー', '', 'ノック音', '発生そ', '', '', '', '抑制する', 'ナチュラル・サウンド・周波数コントロール', '', '採用し', '走り', '滑らかさ', '静かさ', '向上させた', 'JC08モード燃費', '', 'SKYACTIV-D2.2:17.2~18.0km/リッター', 'SKYACTIV-G2.0:16.0km/リッター', 'SKYACTIV-G2.5:14.6~14.8km/リッター', '\n']
    [/code]

    うん、っぽくなってきたので、今日はここまで。

    明日は抽出したキーワードの頻度とかをみることができるようにしよう。

    cx_Freezeでpythonスクリプトをアプリライクに実行できるようにする

    一度書いたファイルが消えたため、再挑戦。
    今回は、せっかく書いたpythonスクリプトを、すぐに実行できる形に、また、他の人にも配りたいという願いから
    cx_Freezeを用いたパッケージ化を行います。

    この問題を解くのに必要な知識

    cx_Freeze
    pip
    setup.py(といっても私もよくわからない・・・)

    導入

    まずは以下のコマンドでインストール

    “`pip install cx_Freeze
    “`

    これで準備は完了です。

    実際にパッケージ化してみる

    パッケージ化したいpythonファイルを「hoge.py」とします
    hoge.pyをお好きなディレクトリにブッコミ、(一番楽なのはcx_freezeを実行する階層と同じ場所だよね)
    次のコマンドを実行します。

    [code lang=text]
    cxfreeze-quickstart
    [/code]

    ってこの話は、公式ドキュメントにいくらでも書いてあるので、僕の話がめちゃくちゃだったらそっち呼んでください
    公式ドキュメント
    そのあとは、ビルドアップまで情報を記入していきます
    python
    “`
    Project name:
    Version 1.0: #バージョンを入力
    Description: #説明を入力
    Python file to make executable from: #パッケージ化したいpyファイル!
    Executable file name []: #上と同じ名前で結構です
    (C)onsole application, (G)UI application, or (S)ervice [C]: #コンソールで動くやつならCでおk
    Save setup script to [setup.py]: #セットアップpyに保存しますか?はい→y
    Overwrite y [n]?: y
    Setup script written to y; run it as:
    python y build
    Run this now [n]?: y
    “`
    このあと、ダララララララ!とビルドアップ処理が始まりますんで。
    すぐに終わりますんで。
    処理が終わったら、実行階層のbuildフォルダ(新しくできているはず)をのぞいて見ましょう
    その中に、フォルダができているはずです。
    hogeというexecファイルと、libやら、dylibやら格納されています
    lib内には、python3モジュールがぶっこまれています。そのままに。
    使い方は簡単
    execファイルをダブルクリックするだけです。
    これで、python hoge.pyと毎回ターミナルで打つ必要は無くなりました。
    今日はココまで。

    【レベル4】Pythonでワードプレスに記事を読み書き投稿するプログラム

    練習問題

    wordpress_xmlrpcを使ってワードプレスに投稿するプログラムを書きなさい。

    この問題を解くのに必要な知識

    特になし

    解説

    ワードプレスに投稿するライブラリが存在します。
    これは、ワードプレスサイトの

    xmlrpc.php

    というphpページにアクセスして投稿できるようにしたものらしいですが、詳しいことはわかりません。素人だもの。
    一つ明らかなのは、こいつをpipでモジュールとしてインストールすれば、Pyhonからワードプレスに記事が投稿可能になるということです。

    python-wordpress_xmlrpcのインストール

    まずはターミナル(Windowsならコマンドプロンプト)を開いて、
    [python]pip install python-wordpress-xmlrpc[/python]
    これでモジュールのインストールが完了しました。

    モジュールのインポート

    from wordpress_xmlrpc import Client, WordPressPost
    from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
    from wordpress_xmlrpc.methods.users import GetUserInfo
    

    ここから具体的に投稿条件を記述していきます。

    wp = Client('http://[サイトのアドレス]/xmlrpc.php', 'ユーザー名', 'ログインパスワード')
    post = WordPressPost()
    post.title = 'タイトル'
    post.content = 'ここに投稿内容'
    post.terms_names = {'post_tag': ['タグ名1','タグ名2'],'category': ['カテゴリ名1','カテゴリ名2']}
    post.status='publish'
    wp.call(NewPost(post))
    

    [サイトのアドレス][ユーザー名][ログインパスワード]を入れれば、すぐに投稿できます。
    一応は、使い勝手が悪すぎますが、Pythonからワードプレスみ投稿する環境ができました。

    解答

    [python]
    from wordpress_xmlrpc import Client, WordPressPost
    from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
    from wordpress_xmlrpc.methods.users import GetUserInfo

    wp = Client(‘http://[サイトのアドレス]/xmlrpc.php’, ‘ユーザー名’, ‘ログインパスワード’)
    post = WordPressPost()
    post.title = ‘タイトル’
    post.content = ‘ここに投稿内容’
    post.terms_names = {‘post_tag’: [‘タグ名1′,’タグ名2′],’category’: [‘カテゴリ名1′,’カテゴリ名2′]}
    post.status=’publish’
    wp.call(NewPost(post))
    [/python]

    ただこれでは使い勝手が悪すぎます。
    もう少し変数を定義してすっきりさせましょう。

    練習問題

    新規にテキストファイルを作成し、随時書き込み、保存したファイルを読み出し、その内容をワードプレスに投稿するプログラムを書きなさい。

    この問題を解くのに必要な知識

  • open() 関数
  • while文
  • 使い勝手をよくしてみる。

    importの部分は省きます
    プレースホルダー を使うと便利です
    [python]
    url='[サイトのアドレス]’
    username='[ユーザー名]’
    password='[パスワード]’
    wp = Client(‘%s’ % url, ‘%s’ % username, ‘%s’ % password)
    post = WordPressPost()
    post.title = ‘タイトル’
    post.content = ‘ここに投稿内容’
    post.terms_names = {‘post_tag’: [‘タグ名1′,’タグ名2′],’category’: [‘カテゴリ名1′,’カテゴリ名2′]}
    post.status=’publish’
    wp.call(NewPost(post))
    [/python]

    タイトルと本文をinput() 形式で入力できるようにする。

    input() を使えば、楽にタイトルと本文を挿入することができます。

    [python]
    p_title=input(‘タイトル名:’)
    p_content=input(‘本文:’)

    post.title=p_title
    post.content=p_content
    [/python]
    これで少しは楽になりました。試しに実行してみると、タイトルと本文を入力すれば投稿することができますね。
    しかしこれではinputが一行しか入力できないので、困ったものです。
    endと入力するまで続けてかけるようにします。

    input() で複数行の入力

    while文 でinput() を繰り返します。
    whileは便利です。個人的にはfor文よりも扱いがし易く、理解しやすいと思っています。
    [python]
    while True:
    text=input("文章を入力:")
    if text=="end":
    break
    [/python]
    このようにしてあげれば、endと入力するまで、書き続けられます。
    しかしこれでは、せっかく書いた文章が保存されません。
    次に、txtファイルに保存する方法を解説します。

    一度ワードプレスのことは忘れて、頭をまっさらにしましょう。

    テキストファイルを作成する

    テキストファイルを新規に作成するには、open() 関数を用います。
    [python]
    p_title=input(‘タイトル:’)
    directory=’ファイルのパス’
    file=open(‘%s/%s.txt’ % (directory,p_title),’a’,encoding=’utf-8′) #書き込み追記モード
    [/python]
    %s/%sの部分がよくわからないかもしれません。

    これは、プレースホルダー を連続して使っています。
    通常であれば、

    '%s' % sample1

     で変数sample1を挿入できますが、複数を異なる場所に挿入したい場合は、

    '%s %s' % (sample1, sample2)

    とします。

    今回は、’ファイルのパス/タイトル.txt’というテキストファイルを作成したかったので、このような形になりました。

    ‘w’は書き込みモードで、開くたびに内容を消去してまっさらな状態から書き込むモードです。

    open() で、モードの選択を行う。
  • ‘r’:読み込みモード
  • ‘w’:書き込み用に開き、まずファイルを切り詰める
  • ‘a’:書き込み用に開き、ファイルが存在する場合は末尾に追記する
  • ‘b’:バイナリモード
  • 使うのはこの4つくらいです。

    今回は、続けて書けるように’a’で開きましょう。
    上の繰り返し入力と合わせてファイルに追記するコードはこのようになります。

    [python]
    p_title=input(‘タイトル:’)
    directory=’ファイルのパス’
    file=open(‘%s/%s.txt’ % (directory,p_title),’a’,encoding=’utf-8′) #書き込み追記モード
    while True: #エラーがなければ延々と繰り返す構文。便利。
    text=input("文章を入力:")
    if text=="end":
    break #whileのループから抜け出す呪文
    else:
    file.write(‘%s\n’ % text) #改行\nを入れないと、詰め詰めになる
    file.close()
    [/python]
    file.write(‘ここに内容’)とすれば、ファイルに書き込みすることができます。
    書き込んだ後は、file.close()で閉じましょう。

    ファイルのパスは、右クリックからoptionキーを押すことでコピーできます。
    MacOSのデスクトップの場合、
    /Users/ユーザー名/Desktop

    がパスになります。

    テキストファイルを読み出し、ワードプレスに投稿する

    これで、新しく作成するメモ帳が完成しましたね。

    次は、こいつを読み込みます。
    [python title=”Pythonコード”]
    file=open(‘%s/%s.txt’ % (directory,p_title),’r’,encoding=’utf-8′)
    [/python]
    モードを’r’に変更することを忘れないようにしましょう。

    ここで、忘れていたワードプレスの呪文を引っ張ってきます。
    [python title=”Pythonコード”]
    file=open(‘%s/%s.txt’ % (directory,p_title),’r’,encoding=’utf-8′)

    wp = Client(‘%s’ % url, ‘%s’ % username, ‘%s’ % password)
    post = WordPressPost()
    post.title = p_title
    post.content = file.read() #ここに、読み込み内容
    post.terms_names = {‘post_tag’: [‘タグ名1′,’タグ名2′],’category’: [‘カテゴリ名1′,’カテゴリ名2′]}
    post.status=’publish’
    wp.call(NewPost(post))
    file.close()
    [/python]
    file.read()とすれば、内容を読み込むことができます。
    file.close()で閉じるのを忘れないようにしましょう。
    これで、新しくメモを作成し、ワードプレスに投稿することができるようになりましたね。
    file.close()で閉じるのを忘れないようにしましょう。

    解答

    [python title=”Pythonコード”]
    from wordpress_xmlrpc import Client, WordPressPost
    from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
    from wordpress_xmlrpc.methods.users import GetUserInfo

    #初期設定欄
    p_title=input(‘タイトル:’)
    directory=’/Users/SeiyaAsada/Desktop’
    url='[サイトのアドレス]’
    username='[ユーザー名]’
    password='[パスワード]’

    #ファイルを書き込み
    file=open(‘%s/%s.txt’ % (directory,p_title),’a’,encoding=’utf-8′)
    while True:
    text=input("文章を入力:")
    if text=="end":
    break
    else:
    file.write(‘%s\n’ % text)
    file.close()

    #ファイルを読み出し、ワードプレスに投稿
    file=open(‘%s/%s.txt’ % (directory,p_title),’r’,encoding=’utf-8′)
    wp = Client(‘%s’ % url, ‘%s’ % username, ‘%s’ % password)
    post = WordPressPost()
    post.title = p_title
    post.content = file.read() #ここに、読み込み内容
    post.terms_names = {‘post_tag’: [‘タグ名1′,’タグ名2′],’category’: [‘カテゴリ名1′,’カテゴリ名2′]}
    post.status=’publish’
    wp.call(NewPost(post))
    file.close()
    [/python]

    書き込み、保存し、追記してワードプレスに投稿する

    次はいよいよ、本格的に投稿プログラムを完成させます。
    ここまで、新たに書き込み、それを投稿するところまで作りましたが、一発で長い文章を書き続けるのは辛いところです。

    タイトルを指定することで追記できますが、「【完成形】Pythonでワードプレスに投稿するプログラム」なんていちいち打って入られません。

    しかも、endと入力した場合にすぐに投稿されてしまいます。

    そこで、os.listdir()を使い、ディレクトリ内のファイルをリストアップします。
    [python title=”Pythonコード”]
    import os
    files = os.listdir(directory)
    [/python]
    これでディレクトリ内のファイルを読み出すことができます。
    あとは、リスト化です。
    [python title=”Pythonコード”]
    import os
    files = os.listdir(directory)
    for i in range(len(files)) : #フォルダ内のファイルリストを表示
    print("%s:%s" % (i,files[i]))
    [/python]
    仮にディレクトリ内に[test1.txt][test2.txt][test3.txt]があるとき、このように表示されます。

    0:test1.txt
    1:test2.txt
    2:test3.txt
    

    あとは、任意の番号を指定するだけでファイルを引っ張り出してくれるコードを記述するだけです。
    [python title=”Pythonコード”]
    files = os.listdir(directory)
    while True:
    for i in range(len(files)) : #フォルダ内のファイルリストを表示
    print("%s:%s" % (i,files[i]))
    #番号を入力させて、エラーが出なければbreakで次へ
    try:
    title=str(files[int(input("番号入力:"))]).replace(".txt","")
    f=open("%s/%s.txt" % (directory,title),"r",encoding="utf-8")
    break
    #エラーが出れば(番号が違う、番号じゃないなど)ループさせる
    except:
    print("番号を入力してください")
    print(file.read()) #開いたファイルを表示してみましょう
    [/python]

    これを、新しくファイルを作成するか、既存のファイルを読み込むか、選択できるようにすればいいわけですね!

    [python title=”Pythonコード”]
    while True:
    new=input(‘\n新規作成?(y/n):’)
    #新規作成を選んだ場合、タイトルを新たに決めて、ファイルを作成します
    if new == "y":
    while True:
    p_title=input(‘タイトルを入力:’)
    if p_title=="":
    print("タイトルが入力されていません。")
    else:
    break
    break
    #既存のファイルを開く場合、指定ディレクトリのフォルダからファイル一覧を出し、選択させます
    elif new== "n":
    files = os.listdir(directory)
    while True:
    for i in range(len(files)) : #フォルダ内のファイルリストを表示
    print("%s:%s" % (i,files[i]))
    #番号を入力させて、エラーが出なければbreakで次へ
    try:
    #replace()で、拡張子を一旦消す。
    p_title=str(files[int(input("番号入力:"))]).replace(".txt","")
    f=open("%s/%s.txt" % (directory,p_title),"r",encoding="utf-8")
    print(f.read()) #ファイルの中身を表示させて、確かめる
    f.close()
    break
    #エラーが出れば(番号が違う、番号じゃないなど)ループさせる
    except:
    print("番号を入力してください")
    break
    #yでもnでもない入力の場合、ループさせる。
    else:
    continue
    f=open("%s/%s.txt" % (directory,p_title),"a",encoding="utf-8")
    [/python]

    これで、新規作成時と既存のファイルを編集する両方に対応できました。

    ただし、まだ問題が残っています。
    このままでは文章をを書き終え、endと入力した場合にすぐにワードプレスに投稿されてしまします。

    投稿するか保存するかの条件

    ファイルを閉じた瞬間に、「ワードプレスに投稿しますか?」と選択可能なコードを入れましょう。
    [python title=”Pythonコード”]
    #ワードプレスに投稿するかどうか
    doupost=input(‘ワードプレスに投稿しますか?(y)’)
    if doupost==’y’:
    f=open("%s/%s.txt" % (directory,p_title),"r",encoding="utf-8")
    print(‘投稿しています…Wait for a second…’)
    wp = Client(‘%s’ % url, ‘%s’ % username, ‘%s’ % password)
    post = WordPressPost()
    post.title = p_title
    post.content = file.read()
    post.terms_names = {‘post_tag’: [‘タグ名1′,’タグ名2′],’category’: [‘カテゴリ名1′,’カテゴリ名2′]}
    post.status=’publish’
    wp.call(NewPost(post))
    file.close()
    print(‘投稿が完了しました。’)
    else:#yとしない場合。
    print(‘投稿をやめました。’)
    [/python]
    これで、ブログ投稿プログラムの完成です。

    いえ、もうひとつ加えましょう。
    ワードプレスに投稿するかしないかに関わらず、全ての作業が完了したら、また続きを編集するか、別のファイルを編集できたらいいですよね。

    全体をwhile文で囲ってあげればよいです。
    [python title=”Pythonコード”]
    while True:
    #[今まで書いたプログラムコード]
    conti=input(‘このまま編集を続けますか?(y):’)
    if conti=="y":
    continue
    else:
    break
    print(‘作業を終了しました。’)
    [/python]
    といった感じにすれば、完成です。

    まとめ

    ここまで解説した内容はそれぞれの箇所でバラバラなので、ちゃんと書きましょう。
    [python title=”Pythonコード”]
    while True:#全体の繰り返し
    while True:#ファイル作成、読み込み時のループ
    new=input(‘\n新規作成?(y/n):’)
    #新規作成を選んだ場合、タイトルを新たに決めて、ファイルを作成します
    if new == "y":
    while True:
    p_title=input(‘タイトルを入力:’)
    if p_title=="":
    print("タイトルが入力されていません。")
    else:
    break
    break
    #既存のファイルを開く場合、指定ディレクトリのフォルダからファイル一覧を出し、選択させます
    elif new== "n":
    files = os.listdir(directory)
    while True:
    for i in range(len(files)) : #フォルダ内のファイルリストを表示
    print("%s:%s" % (i,files[i]))
    #番号を入力させて、エラーが出なければbreakで次へ
    try:
    #replace()で、拡張子を一旦消す。
    p_title=str(files[int(input("番号入力:"))]).replace(".txt","")
    f=open("%s/%s.txt" % (directory,p_title),"r",encoding="utf-8")
    print(f.read()) #ファイルの中身を表示させて、確かめる
    f.close()
    break
    #エラーが出れば(番号が違う、番号じゃないなど)ループさせる
    except:
    print("番号を入力してください")
    break
    #yでもnでもない入力の場合、ループさせる。
    else:
    continue
    #文章の編集開始
    f=open("%s/%s.txt" % (directory,p_title),"a",encoding="utf-8")
    while True:
    text=input("文章を入力:")
    if text=="end":
    break
    else:
    file.write(‘%s\n’ % text)
    file.close()

    #ファイルを読み出し、ワードプレスに投稿
    file=open(‘%s/%s.txt’ % (directory,p_title),’r’,encoding=’utf-8′)
    doupost=input(‘ワードプレスに投稿しますか?(y)’)
    if doupost==’y’:
    f=open("%s/%s.txt" % (directory,p_title),"r",encoding="utf-8")
    print(‘投稿しています…Wait for a second…’)
    wp = Client(‘%s’ % url, ‘%s’ % username, ‘%s’ % password)
    post = WordPressPost()
    post.title = p_title
    post.content = file.read()
    post.terms_names = {‘post_tag’: [‘タグ名1′,’タグ名2′],’category’: [‘カテゴリ名1′,’カテゴリ名2′]}
    post.status=’publish’
    wp.call(NewPost(post))
    file.close()
    print(‘投稿が完了しました。’)
    else:#yとしない場合。
    print(‘投稿をやめました。’)
    conti=input(‘このまま編集を続けますか?(y):’)
    if conti=="y":
    continue
    else:
    break
    print(‘作業を終了しました。’)
    [/python]

    ふぅ、ちゃんと動いてくれることを願っています。
    もしかすると、インデントの違いでエラーが出る可能性はありますが、適宜修正してください。

    また、以下に究極形のコードを公開しておきます。

    究極形でできること

  • ディレクトリを選択
  • 複数のWPアカウントから選択
  • ファイルを新規作成
  • ファイルを読み出し
  • 読み出し時に保存内容を確認
  • 編集時のスニペット登録・呼び出し
  • 投稿時に[下書き]or[公開]
  • 投稿時にカテゴリ追加
  • どうぞ。
    ちなみに、この記事はこれで作ったプログラムで書いて投稿しています。

    [python]
    import os #フォルダの中身を探る
    import sys #プログラム強制終了用
    from wordpress_xmlrpc import Client, WordPressPost
    from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
    from wordpress_xmlrpc.methods.users import GetUserInfo

    #スニペット中のendを入力するまで繰り返し書かせる子プログラムの定義
    def write_roop():
    i=1
    while True:
    text=input(‘%s:’ % i)
    if text==’end’:
    break
    else:
    f.write(‘%s\n’ % text)
    i+=1
    continue

    #ディレクトリ選択
    place=["Desktop","User"]
    print("———————–")
    for i in range(int(len(place))):
    print("%s:%s" % (i,place[i]))
    print("———————–")
    while True:
    select=input("どのディレクトリで作業しますか?:")
    if select=="0":
    directory="/Users/ユーザー名/Desktop"
    break
    elif select=="1":
    directory="/Users/ユーザー名"
    break
    else:
    continue

    #どのアカウントを使用するか
    account=["アカウント1","アカウント2"]
    print("———————–")
    for i in range(int(len(account))):
    print("%s:%s" % (i,account[i]))
    print("———————–")
    while True:
    page=input("どのアカウントで投稿しますか?:")
    if page=="0":
    url="アカウント1のURL"
    username="アカウント1のユーザー名"
    password="アカウント1ののパスワード"
    break
    elif page=="1":
    url="アカウント2のURL"
    username="アカウント2のユーザー名"
    password="アカウント2ののパスワード"
    break
    else:
    continue

    while True: #最後の編集を続ける選択をした場合のループ
    #書き始めを決定します
    while True:
    new=input(‘\n新規作成?(y/n):’)
    #新規作成を選んだ場合、タイトルを新たに決めて、ファイルを作成します
    if new == "y":
    while True:
    title=input(‘タイトルを入力:’)
    if title=="":
    print("タイトルが入力されていません。")
    else:
    break
    break
    #既存のファイルを開く場合、指定ディレクトリのフォルダからファイル一覧を出し、選択させます
    elif new== "n":
    files = os.listdir(directory)
    while True:
    for i in range(len(files)) : #フォルダ内のファイルリストを表示
    print("%s:%s" % (i,files[i]))
    #番号を入力させて、エラーが出なければbreakで次へ
    try:
    title=str(files[int(input("番号入力:"))]).replace(".txt","")
    f=open("%s/%s.txt" % (directory,title),"r",encoding="utf-8")

    print(”’

    ファイルの内容

                    ''')
                    print(f.read())
    

    print(”’


                    ''')
                    f.close()
                    break
                #エラーが出れば(番号が違う、番号じゃないなど)ループさせる
                except:
                    print(&quot;番号を入力してください&quot;)
            break
        #endと入力した場合、強制終了
        elif new==&quot;end&quot;:
            sys.exit()
        #yでもnでもendでもない入力の場合、ループさせる。
        else:
            continue
    f=open(&quot;%s/%s.txt&quot; % (directory,title),&quot;a&quot;,encoding=&quot;utf-8&quot;)
    
    #本文を繰り返し入力させる
    while True:
        content=input(&quot;文章を入力(or end):&quot;)
        #endと打てば本文入力終了
        if content==&quot;end&quot;:
            break
    
        #見出し1
        elif content=='#':
            f.write('&lt;h1&gt;%s&lt;/h1&gt;\n' % input(&quot;&lt;h1&gt;&quot;))
            print('&lt;/h1&gt;')#視覚的な補助
    
        #見出し2
        elif content=='##':
            f.write('&lt;h2&gt;%s&lt;/h2&gt;\n' % input(&quot;&lt;h2&gt;&quot;))
            print('&lt;/h2&gt;')#視覚的な補助
    
        #見出し3
        elif content=='###':
            f.write('&lt;h3&gt;%s&lt;/h3&gt;\n' % input(&quot;&lt;h3&gt;&quot;))
            print('&lt;/h3&gt;')#視覚的な補助
    
        #list
        #見出し3
        elif content=='li':
            f.write('&lt;li&gt;%s&lt;/li&gt;\n' % input(&quot;&lt;li&gt;&quot;))
            print('&lt;/&gt;')#視覚的な補助
    
        #pre
        elif content=='pre':
            f.write('&lt;pre&gt;')
            print('&lt;pre&gt;')#視覚的な補助
            write_roop()
            f.write('&lt;/pre&gt;\n')
            print('&lt;/pre&gt;')#視覚的な補助
    
        #その他普通の文字列はそのまま書き込み
        else:
            f.write(&quot;%s\n&quot; % content)
    #最後にファイルを閉じる
    f.close()
    print(&quot;保存しました。&quot;)
    
    #ワードプレスに投稿するかどうか
    doupost=input('ワードプレスに投稿しますか?(y)')
    if doupost=='y':
        f=open(&quot;%s/%s.txt&quot; % (directory,title),&quot;r&quot;,encoding=&quot;utf-8&quot;)
        #カテゴリー設定
        category=[]
        while True:
            cat=str(input(&quot;カテゴリーを入力:&quot;))
            if cat==&quot;end&quot;:
                break
            category.append(cat)
        while True:
            dp=input('下書き(draft)か公開(publish)を選択してください。(d/p)')
            if dp=='p':
                p_status='publish'
                break
            elif dp=='d':
                p_status='draft'
                break
            else:
                continue
        print('投稿しています...Wait for a second...')
    
        wp = Client('%s/xmlrpc.php' % url, username, password)
        post = WordPressPost()
        post.title = title
        post.content = f.read()
        post.terms_names = {'post_tag': [],'category': category}
        post.status=p_status
        wp.call(NewPost(post))
    
        f.close()
        print('投稿が完了しました。')
    else:
        print('投稿をやめました。')
    
    #最後に、編集を続けるかどうかの条件。yで、最初に戻り、新規作成と既存のファイルの編集が出来る。
    while True:
        conti=input(&quot;編集を続けますか?(y/n)&quot;)
        if conti==&quot;y&quot;:
            break
        elif conti==&quot;n&quot;:
            print(&quot;作業を終了します。&quot;)
            sys.exit()
        else:
            print(&quot;入力してください&quot;)
            continue
    

    [/python]

    google.py:検索結果を取得するモジュール

    ここで学ぶこと

    google検索結果を取得する方法

    なかなか見つからない

    Google検索結果の取得は、ネットを探してもなかなかみつからない。
    理由はよく分からないけれど、そもそも「PythonでGoogle検索結果」を調べたい時にどう検索すれば良いかわからない

    そして求めていた情報が!nktmemoさんのページ。


    この、ありふれたテーマについて書きましょう。 方法がいろいろありすぎて、1日ほど費やしてしまった。 そして、ま…

    google.py

    インストール

    こちらでいけます。

    “`pip insatall google“`

    使いかた

    [python title=”Pythonコード”]
    from google import search
    for url in search(‘"Breaking Code" WordPress blog’, stop=20):
    print(url)
    “`

    本当は、stop=[数字]で出したい検索結果数をコントロールできるみたいなんだけど、なぜかどんな場合も15個が表示されてしまう。

    ここら辺は、いろいろいじってみて解決したら、追記しますが、とりあえず使えます。

    ソースサイト


    Quick script in Python to make Google searches. Can be used as a command line script or imported as a module. Download: http://winappdbg.sourceforge.net/blog/google-1.03.tar.gz

    乱数の妥当性を確かめるプログラム

    この記事を理解するのに必要な知識

  • random モジュール
  • def 定義の記述
  • for文
  • while文
  • プレースホルダー
  • 乱数がどこまで偏るのか

    [python title=”Python”]
    import random
    testnum=60 #乱数を繰り出す回数
    min_num=-6 #乱数の最小値
    max_num=6 #乱数の最大値
    find_num=0 #でてきた乱数から検証したい数
    expect=round(testnum*(1/(abs(min_num)+abs(max_num)+1)))
    numlist = []
    def caos(num):
    x=0
    for i in range(num):
    value=random.randint(min_num,max_num)
    n=str(value)
    numlist.append(n)
    x+=int(numlist[i])
    print(numlist)
    print("合計:%s" % x)
    caos(testnum)
    zerolist=[]
    while str(find_num) in numlist:
    zero = int(numlist.index(str(find_num)))
    zerolist.append(numlist[zero])
    numlist.remove(str(find_num))
    zeronumbers=len(zerolist)
    print("%sはおおよそ%s個見つかると期待して良いはずです。" % (find_num,expect))
    print("実際に%sは%s個ありました。" % (find_num, zeronumbers))
    “`

    実行結果

    “`
    [‘-5’, ‘5’, ‘-3’, ‘1’, ‘1’, ‘-5’, ‘0’, ‘-2’, ‘6’, ‘4’, ‘2’, ‘5’, ‘2’, ‘6’, ‘0’, ‘6’, ‘-3’, ‘-1’, ‘2’, ‘0’, ‘4’, ‘5’, ‘-1’, ‘0’, ‘-3’, ‘-6’, ‘-3’, ‘-3’, ‘1’, ‘-4’, ‘-4’, ‘-6’, ‘-3’, ‘-1’, ‘-1’, ‘-4’, ‘5’, ‘5’, ‘5’, ‘-3’, ‘1’, ‘-3’, ‘0’, ‘-6’, ‘-4’, ‘-2’, ‘2’, ‘-5’, ‘3’, ‘3’, ‘-4’, ‘0’, ‘2’, ‘-4’, ‘1’, ‘0’, ‘-2’, ‘-5’, ‘0’, ‘-4’, ‘-4’, ‘1’, ‘2’, ‘0’, ‘-5’, ‘-2’, ‘-3’, ‘-1’, ‘-2’, ‘-3’, ‘2’, ‘4’, ‘-4’, ‘-6’, ‘6’, ‘-3’, ‘3’, ‘1’, ‘-3’, ‘3’, ‘-1’, ‘1’, ‘-1’, ‘0’, ‘-5’, ‘-5’, ‘-5’, ‘-5’, ‘-5’, ‘6’, ‘1’, ‘-1’, ‘-2’, ‘-2’, ‘-1’, ‘-5’, ‘0’, ‘4’, ‘-5’, ‘4’, ‘-5’, ‘-5’, ‘2’, ‘4’, ‘-1’, ‘-1’, ‘-4’, ‘-3’, ‘4’, ‘1’, ‘-5’, ‘3’, ‘0’, ‘-6’, ‘-5’, ‘1’, ‘0’, ‘-1’, ‘2’, ‘-3’, ‘-3’, ‘-5’, ‘0’, ‘2’, ‘3’, ‘-6’, ‘-6’, ‘-6’, ‘1’, ‘-6’, ‘-3’, ‘-2’, ‘6’, ‘3’, ‘-4’, ‘0’, ‘1’, ‘-4’, ‘-5’, ‘2’, ‘0’, ‘2’, ‘5’, ‘2’, ‘-5’, ‘4’, ‘-4’, ‘6’, ‘-3’, ‘-5’, ‘6’, ‘-2’, ‘1’, ‘4’, ‘-6’, ‘5’, ‘-1’, ‘-5’, ‘-5’, ‘0’, ‘-3’, ‘2’, ‘-5’, ‘3’, ‘-5’, ‘-5’, ‘-4’, ‘0’, ‘-1’, ‘0’, ‘2’, ‘-3’, ‘3’, ‘-6’, ‘1’, ‘-4’, ‘6’, ‘-5’, ‘-4’, ‘-4’, ‘6’, ‘4’, ‘6’, ‘-2’, ‘-3’, ‘-1’, ‘5’, ‘-5’, ‘-1’, ‘-2’, ‘5’, ‘-4’, ‘-4’, ‘1’, ‘1’, ‘-3’, ‘-5’, ‘-1’, ‘5’, ‘-5’, ‘4’, ‘5’, ‘4’, ‘-6’, ‘-2’, ‘2’, ‘-6’, ‘-1’, ‘2’, ‘-1’, ‘-4’, ‘6’, ‘2’, ‘-3’, ‘2’, ‘5’, ‘3’, ‘-3’, ‘-6’, ‘3’, ‘-1’, ‘-6’, ‘-3’, ‘-5’, ‘-2’, ‘4’, ‘-3’, ‘-3’, ‘-2’, ‘1’, ‘-1’, ‘-2’, ‘-2’, ‘-2’, ‘1’, ‘3’, ‘5’, ‘0’, ‘-2’, ‘-2’, ‘1’, ‘1’, ‘4’, ‘3’, ‘5’, ‘4’, ‘-6’, ‘-4’, ‘3’, ‘0’, ‘1’, ‘2’, ‘-6’, ‘3’, ‘6’, ‘5’, ‘4’, ‘-1’, ‘3’, ‘0’, ‘0’, ‘3’, ‘-6’, ‘5’, ‘-5’, ‘4’, ‘-1’, ‘3’, ‘0’, ‘1’, ‘-5’, ‘-4’, ‘-3’, ‘0’, ‘5’, ‘-5’, ‘6’, ‘1’, ‘1’, ‘-4’, ‘2’, ‘-5’, ‘4’, ‘2’, ‘5’, ‘1’, ‘-2’, ‘-5’, ‘-6’, ‘1’, ‘5’, ‘-3’, ‘-1’, ‘-3’, ‘-5’, ‘3’, ‘-3’, ‘-4’, ‘1’, ‘-1’, ‘2’, ‘5’, ‘-6’, ‘0’, ‘-3’, ‘-5’, ‘1’, ‘-5’, ‘1’, ‘-5’, ‘-3’, ‘4’, ‘-1’, ‘3’, ‘3’, ‘-2’, ‘3’, ‘-5’, ‘6’, ‘4’, ‘-1’, ‘2’, ‘-3’, ‘-6’, ‘5’, ‘4’, ‘-3’, ‘-3’, ‘6’, ‘-1’, ‘-1’, ‘1’, ‘0’, ‘-2’, ‘3’, ‘-4’, ‘-4’, ‘2’, ‘5’, ‘5’, ‘-1’, ‘-2’, ‘0’, ‘-6’, ‘-6’, ‘-3’, ‘-2’, ‘4’, ‘0’, ‘0’, ‘5’, ‘4’, ‘-5’, ‘4’, ‘-5’, ‘-4’, ‘3’, ‘1’, ‘-5’, ‘-4’, ‘5’, ‘6’, ‘-4’, ‘3’, ‘-4’, ‘0’, ‘6’, ‘1’, ‘3’, ‘-3’, ‘-1’, ‘3’, ‘-4’, ‘-5’, ‘-1’, ‘-3’, ‘-6’, ‘-1’, ‘-3’, ‘0’, ‘1’, ‘-6’, ‘-6’, ‘-5’, ‘0’, ‘-3’, ‘5’, ‘4’, ‘-2’, ‘-2’, ‘-2’, ‘-2’, ‘-2’, ‘-4’, ‘3’, ‘-5’, ‘-6’, ‘-3’, ‘-6’, ‘1’, ‘-3’, ‘2’, ‘-3’, ‘-4’, ‘1’, ‘-2’, ‘2’, ‘-2’, ‘-2’, ‘5’, ‘-4’, ‘-4’, ‘0’, ‘4’, ‘-1’, ‘-2’, ‘-2’, ‘-1’, ‘-2’, ‘-4’, ‘-6’, ‘1’, ‘-1’, ‘-4’, ‘-1’, ‘-2’, ‘2’, ‘-3’, ‘-2’, ‘6’, ‘0’, ‘-1’, ‘2’, ‘-6’, ‘0’, ‘5’, ‘-6’, ‘-2’, ‘6’, ‘-4’, ‘5’, ‘6’, ‘1’, ‘2’, ‘0’, ‘-1’, ‘1’, ‘-6’, ‘-5’, ‘1’, ‘-2’, ‘-4’, ‘-2’, ‘-6’, ‘-6’, ‘0’, ‘-3’, ‘3’, ‘-2’, ‘-4’, ‘6’, ‘-4’, ‘4’, ‘-1’, ‘-6’, ‘-5’, ‘-5’, ‘5’, ‘-1’, ‘6’, ‘0’, ‘-5’, ‘3’, ‘6’, ‘-5’, ‘5’, ‘-6’, ‘1’, ‘3’, ‘-2’, ‘3’, ‘0’, ‘5’, ‘5’, ‘-1’, ‘-4’, ‘-6’, ‘-6’, ‘-5’, ‘0’, ‘-5’, ‘-4’, ‘2’, ‘1’, ‘3’, ‘5’, ‘0’, ‘-6’, ‘2’, ‘0’, ‘5’, ‘-4’, ‘6’, ‘-2’, ‘-3’, ‘-1’, ‘-1’, ‘-6’, ‘-5’, ‘5’, ‘4’, ‘6’, ‘3’, ‘-4’, ‘1’, ‘6’, ‘-2’, ‘4’, ‘-1’, ‘4’, ‘-6’, ‘-6’, ‘-6’, ‘2’, ‘-5’, ‘-2’, ‘-2’, ‘4’, ‘-5’, ‘3’, ‘5’, ‘4’, ‘6’, ‘-5’, ‘-5’, ‘-1’, ‘1’, ‘0’, ‘4’, ‘0’, ‘-5’, ‘-6’, ‘3’, ‘1’, ‘4’, ‘-2’, ‘2’, ‘-5’, ‘-4’, ‘-1’, ‘-5’, ‘2’, ‘-2’, ‘5’, ‘2’, ‘0’, ‘-5’, ‘5’, ‘3’, ‘-2’, ‘-5’, ‘4’, ‘5’, ‘2’, ‘6’, ‘2’, ‘-1’, ‘-5’, ‘-3’, ‘0’, ‘-1’, ‘-2’, ‘2’, ‘-2’, ‘-6’, ‘-6’, ‘-1’, ‘5’, ‘0’, ‘1’, ‘4’, ‘0’, ‘6’, ‘-2’, ‘2’, ‘6’, ‘4’, ‘-3’, ‘-1’, ‘-6’, ‘1’, ‘1’, ‘4’, ‘-1’, ‘-5’, ‘3’, ‘4’, ‘-3’, ‘-6’, ‘2’]
    合計:-304
    0はおおよそ46個見つかると期待して良いはずです。
    実際に0は49個ありました
    “`

    となりました。
    やはり合計値が0周辺に来ないのは、試行回数が多ければ多いほど起こることなのでしょう。
    求めた数字が出てくる期待値は、試行回数が多ければあたりに近くなりますね。

    スクロールの疲れを知らないなら、10000くらいまでやっても大丈夫です。

    追記

    100000で試しました。

    “`
    合計:-7
    0はおおよそ7692個見つかると期待して良いはずです。
    実際に0は7444個ありました。
    “`

    なんと、合計値が-7に落ち着きました。

    追記2

    なんとか、合計値の推移を視覚化できないかと考えて、下のプログラムを書きました。

    [python title=”Python”]
    import turtle
    import random
    testnum=60 #乱数を繰り出す回数
    min_num=-6 #乱数の最小値
    max_num=6 #乱数の最大値
    find_num=0 #でてきた乱数から検証したい数

    def real_random(testnum,min_num,max_num,find_num):
    expect=round(testnum(1/(abs(min_num)+abs(max_num)+1)))
    numlist=[]
    sumlist=[0]
    def caos(num):
    x=0 #合計値(初期値0)
    for i in range(num):
    value=random.randint(min_num,max_num)
    n=str(value)
    numlist.append(n) #乱数の出現リスト
    x+=int(numlist[i])
    sumlist.append(x) #合計値の推移リスト
    print("合計:%s" % x)
    caos(testnum)
    zerolist=[]
    while str(find_num) in numlist:
    zero = int(numlist.index(str(find_num)))
    zerolist.append(numlist[zero])
    numlist.remove(str(find_num))
    zeronumbers=len(zerolist)
    print("%sはおおよそ%s個見つかると期待して良いはずです。" % (find_num,expect))
    print("実際に%sは%s個ありました。" % (find_num, zeronumbers))
    t=turtle
    forwardlen=5
    steplen=1
    t.forward(1)
    for i in range(1,testnum+1):
    next_step=sumlist[i]-sumlist[i-1]
    if next_step<0:
    t.right(90)
    t.forward(abs(next_step)steplen)
    t.left(90)
    t.forward(forwardlen)
    elif next_step == 0:
    t.forward(forwardlen)
    elif next_step>0:
    t.left(90)
    t.forward(abs(next_step)*steplen)
    t.right(90)
    t.forward(forwardlen)
    real_random(testnum,min_num,max_num,find_num)
    “`

    こいつは、turtle モジュールを使って、1つ乱数が生成されるたびに右に移動&差分を縦に移動という命令を出してアニメーションにしています。

    実行結果

    合計:12
    0はおおよそ5個見つかると期待して良いはずです。
    実際に0は5個ありました。
    %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88

    追記2の追記

    [python title=”Python”]
    elif next_step == 0:
    t.forward(forwardlen)</code>
    “`

    の部分を、以下に差し替えると、検証したい数字が現れた場所で一回転してくれます。(この場合、ゼロ)

    “`py
    elif next_step == 0:
    t.left(90)
    t.forward(3)
    t.right(120)
    for py in range(6):
    t.forward(3)
    t.right(60)
    t.right(60)
    t.forward(3)
    t.left(90)
    t.forward(forwardlen)

    “`

    %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-1

    追記3(これが最強)

    [python title=”Python”]
    import turtle
    import random
    testnum=100 #乱数を繰り出す回数
    min_num=-6 #乱数の最小値
    max_num=6 #乱数の最大値
    find_num=0 #でてきた乱数から検証したい数
    try=5 #試行回数

    def real_random(testnum,min_num,max_num,find_num):
    expect=round(testnum(1/(abs(min_num)+abs(max_num)+1)))
    numlist=[]
    sumlist=[0]
    def caos(num):
    x=0 #合計値(初期値0)
    for i in range(num):
    value=random.randint(min_num,max_num)
    n=str(value)
    numlist.append(n) #乱数の出現リスト
    x+=int(numlist[i])
    sumlist.append(x) #合計値の推移リスト
    print(numlist)
    print("合計:%s" % x)
    caos(testnum)
    zerolist=[]
    while str(find_num) in numlist:
    zero = int(numlist.index(str(find_num)))
    zerolist.append(numlist[zero])
    numlist.remove(str(find_num))
    zeronumbers=len(zerolist)
    print("%sはおおよそ%s個見つかると期待して良いはずです。" % (find_num,expect))
    print("実際に%sは%s個ありました。" % (find_num, zeronumbers))
    t=turtle
    forwardlen=5
    multiple=2
    t.setpos(-400, 0)
    t.forward(800)
    t.penup()
    t.setpos(-400, 0)
    t.pendown()
    for i in range(1,testnum+1):
    next_step=sumlist[i]-sumlist[i-1]
    if next_step&gt;0:
    t.right(90)
    t.forward(abs(next_step)multiple)
    t.left(90)
    t.forward(forwardlen)
    t.write(next_step)
    t.forward(forwardlen)
    elif next_step == find_num:
    t.color(‘red’)
    if find_num&gt;0:
    t.right(90)
    t.forward(abs(next_step)multiple)
    t.left(90)
    t.forward(forwardlen)
    t.write(find_num)
    t.forward(forwardlen)
    elif find_num==0:
    t.forward(forwardlen)
    t.write(find_num)
    t.forward(forwardlen)
    elif find_num&lt;0:
    t.left(90)
    t.forward(abs(next_step)multiple)
    t.right(90)
    t.forward(forwardlen)
    t.write(find_num)
    t.forward(forwardlen)
    t.color(‘black’)
    elif next_step&lt;0:
    t.left(90)
    t.forward(abs(next_step)*multiple)
    t.right(90)
    t.forward(forwardlen)
    t.write(next_step)
    t.forward(forwardlen)
    t.penup()
    t.setpos(-400, 0)
    t.pendown()
    for repeat in range(try):
    real_random(testnum,min_num,max_num,find_num)
    “`

    これが最強だと思う。
    線もひいてくれる上に目的の数字に色付け、自動試行繰り返し機能付き
    %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-1

    追記4

    しばらく繰り返してみた結果

    下の図のように、乱数の偏りは二次関数的に広がっていくことが示唆される。
    %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-01-13-50-40

    これは、非常に面白い!

    Beautifulsoup4を使ってWEBスクレイピングを行う

    – Beautiful4を使ってスクレイピングをする
    – リストから全て羅列させる方法を知る

    今回は、Beautifulsoup4の呪文をつかって、スクレイピングしたいと思います。

    ライブラリのインストールがまだの方は、以下のコマンド

    “`py
    pip install beautifulsoup4
    “`

    Anacondaを立ち上げ、Jupyter notebookを起動します。

    Anacondaってなに?という人は以下の記事を参照あれ


    Anaconda4.xのインストール Macに搭載されているPythonが2.7なので、ちゃんとした3系の環境を構築する必要があります。 ここで、面倒くさいことを全部避けまして、Anacondaをインストールします。 ターミナルからインストールする方法もありますが、素人にはいつも通りのやり方が一番。 Anac

    htmlソースを抽出してみる

    「ひとりPython3修練所の最初の記事(http://hitoripython.wpblog.jp/archives/15)」をターゲットにします。

    【python】

    “`py
    from urllib import request
    from bs4 import BeautifulSoup
    html = request.urlopen(‘http://hitoripython.wpblog.jp/archives/15’)
    soup = BeautifulSoup(html, “lxml”
    print(soup)
    “`

    こいつをコピペして、実行してみると、
    ダアアアアアアアアアっと出てくると思います。

    これがウェブサイトの中身(=ソースコード)ですね。

    いつもあなたが見ている綺麗で整ったページはこのようにして作られています。って知ってるかそれくらい。

    これであなたは立派にスクレイピングを行なうことができるようになったのです。

    今度はその中から、タイトルだけを抽出してみましょう。

    以下のコードに差し替えます。

    全てのh1タグをリスト化

    【Python】

    [python title=”Python”]from urllib import request
    from bs4 import BeautifulSoup
    html = request.urlopen(‘http://hitoripython.wpblog.jp/archives/15’)
    soup = BeautifulSoup(html, “lxml”)
    titles = soup.findAll(“h1”) #soupからh1タグが付いているものを全て抽出
    #↑すきな名前
    print(titles) #titlesを書き出し“`

    これでh1タグが付いた全てのタイトルがリスト化できました

    でもこれじゃあ見にくいじゃないか。

    ということで、リスト化されたtitlesの中から全てを抜き出し切るまで順番に表示させましょう。

    リストから全て書き出す

    [python title=”Python”]from urllib import request
    from bs4 import BeautifulSoup
    html = request.urlopen(‘http://hitoripython.wpblog.jp/archives/15’)
    soup = BeautifulSoup(html, “lxml”)
    for titles in soup.findAll(“h1″): #for文という構文を使います
    print(titles) #titlesを書き出し“`

    “`
    <h1 class=”entry-title”>Python3について</h1>
    <h1><span id=”i”>はじめに</span></h1>
    <h1><span id=”Python”>Pythonとは</span></h1>
    <h1><span id=”Python-2″>なぜPythonなのか</span></h1>
    <h1><span id=”i-4″>使えるようにするには</span></h1>“`

    いいですね!これでますます見やすくなりました。

    しかし、このh1タグがいりませんよね。
    そんな時は、テキスト化させちゃいましょう。

    抽出した文をtext化

    “`py
    from urllib import request
    from bs4 import BeautifulSoup
    html = request.urlopen(‘http://hitoripython.wpblog.jp/archives/15’)
    soup = BeautifulSoup(html, “lxml”)
    for titles in soup.findAll(“h1”): #soupからh1タグが付いているものを全て抽出
    print(titles.text) #titlesを書き出し
    “`

    “`
    Python3について
    はじめに
    Pythonとは
    なぜPythonなのか
    使えるようにするには
    “`

    これで完璧に、タイトルだけをさっと見られるようになりましたね!

    こんな感じに、Beautifulsoup4はWEBページをスクレイピングし、そのなかの必要な情報を選別することが可能になるのです。

    ちなみに、以下のように書き換えることも可能です。

    “`py
    from urllib import request
    from bs4 import BeautifulSoup
    html = request.urlopen(‘http://hitoripython.wpblog.jp/archives/15’)
    soup = BeautifulSoup(html, “lxml”)
    titles = soup.findAll(“h1”)
    list_num = len(titles)#リスト内の数を割り出す
    x=0
    while x &ht;= list_num-1:#繰り返し指定
    print(titles[x].text)#x番目を書き出し
    x+=1 #書き出したらxを1つ進める
    “`

    こちらの方が、文字数は増えましたが何を言っているのかわかりやすくなっていると思います。

    まず、
    list_num = len(titles)はlen()という数を測るマジナイを使ってリストの中にある要素の数をカウントしています。

    list = [“a”,”b”,”c”,”d”,”e”]
    リストの番号は、0,1,2,3・・・とカウントしていきます。
    したがって、リストの2番目を出したい場合、
    “`py
    print(list[1])
    “`
    と記述しなければなりません。

    したがって、x=0とした上で4までカウントしてあげることで、5つの要素全てを読み込むことになるんですね。
    while文というものも使っていますが、こちらは簡単に説明すると、「whileの条件下にある間はこれを繰り返す」というおまじないになります。

    つまり、

    “`py
    while x &ht;= list_num-1:
    “`

    というのは、「xが4以下の間はずっと:」ということになります。
    なのでその次に書くのは、Tabを入れた上で

    “`py
    print(titles[x].text)
    “`

    となります。
    ちなみに、<=という部分は、≦です。もし仮に「より小さい」という記述にするのであれば、<となります。

    しかし、このまま実行してしまうととても恐ろしいことになります。
    x=0と指定しているので、xが0である限り、繰り返しの条件に当てはまってしまうので、リストの1番目を延々と書き出す無限ループに陥ってしまいます。

    したがって、xを1回ずつ増やしてあげなければなりません。
    つまり、printした後に

    “`py
    x += 1
    (以下と同義
    x = x+1
    “`

    を記述してあげることで、xが4となるまでこれを繰り返してくれるようになります。

    ね、簡単でしょう。

    ここで問題

    list = ["東京","埼玉","千葉","神奈川","京都","大阪","兵庫","和歌山"]
    ```
    の時、関西圏の府県のみを書き出すプログラムを完成させなさい。

    ヒント

    関西圏は、リストの5番目〜8番目になるので、これを抽出させればよいというわけですね。

    カウントさせるxの初期値を決めます。

    ```py
    x = 4
    ```

    あとは、このxが7になるまでの間、x番目(実際にはx+1番目)の要素をprintさせるというwhile文を記述すれば完成です。

    ```py
    while x &ht;= 7:
    print(list[x])
    x+=1
    ```

    ```py
    list = ["東京","埼玉","千葉","神奈川","京都","大阪","兵庫","和歌山"]
    x=4
    while x &ht;= 7:
    print(list[x])
    x+=1
    ```
    ```
    京都
    大阪
    兵庫
    和歌山
    ```