2018年8月7日火曜日

Python本22冊を読み比べたなまけ者のPython初学者が、交通費のスクレイピングに挑戦してみた

勉強の為に転載しました。
https://www.google.co.jp/amp/ascii.jp/elem/000/001/721/1721241/amp/

「なまけ者になりなさい」

 Python入門書22冊を読み比べてみたものの、コードがどんどん書けるまでには至らず、スーパー初学者のまま、Python学習が停滞している。その原因は明白だ。1つは手をあまり動かしていないこと、もう1つはPythonを学ぶ明確な目標がないからだ。
 「わかっているならやれよと」いうお叱りの声が聞こえてきそうだが、楽な方に流れるのが人間というもの。あの水木しげる先生も「なまけ者になりなさい」とおっしゃっている。しかし、Python入門書を読んでいると、「Pythonには、簡単にプログラムを開発するために、便利な道具がさまざまに用意されています」(山田祥寛・山田奈美著『3ステップでしっかり学ぶ Python入門』技術評論社)、「『めんどくさくて無理~』ってことは、コンピューターにやってもらえばいいんだよね」(森巧尚著『Python 1年生 体験してわかる!会話でまなべる!プログラミングのしくみ』翔泳社)などという文言が散見される。オライリー・ジャパンからは『退屈なことはPythonにやらせよう』(Al Sweigart著、相川愛三訳)という書名の本が出版されているぐらいだ。つまり、なまけ者こそPythonを学ぶべきできなのである。では、何をPythonにやらせるべきなのか。筆者は会社員なので、なまけたい作業をいくつか列挙してみた。
  • 報告書が面倒。というか、タイピングそのものが面倒。
  • メールの返信が面倒。AIが自分っぽい返信をしてくれるとありがたい。
  • 交通費の精算で交通費を1つ1つ調べるのが面倒。
  • 昼食に何を食べようか考えるのが面倒。
  •  この中から、今回は交通費をスクレイピングするプログラムに取り組むことにした。これは弊社が交通費の精算をその都度ではなく、月末に提出することに起因する。月末になると、筆者はその月の外出先と交通ルートを思い出し、1つ1つ交通費を検索するという作業を行っている(そもそもまとめてやるのがダメなのはわかっているが)。これを一括で調べたいというのが、今回の目標だ。

    便利なライブラリー「BeautifulSoup」

     Pythonには便利なライブラリーがそろっている。「BeautifulSoup」はHTMLを解析するライブラリーで、Webスクレイピングといえば、このライブラリーが定番だ。入門書やWEBサイトを参考に、例として、市ヶ谷⇒飯田橋、渋谷⇒目黒、溜池山王⇒亀戸の交通費を一括で調べるため、筆者が書いたコードは次の通りだ。
    
    
    import requests, sys, webbrowser from bs4 import BeautifulSoup
    r = requests.get("http://google.com/", "市ヶ谷 飯田橋 交通費") soup = BeautifulSoup(r.text, 'lxml')
    num_open = min(1, len(link_elems)) for i in range(num_open): webbrowser.open("http://google.com",link_elems[i].get("href"))
    r = requests.get("http://google.com/", "渋谷 目黒 交通費") soup = BeautifulSoup(r.text, 'lxml')
    num_open = min(1, len(link_elems)) for i in range(num_open): webbrowser.open("http://google.com",link_elems[i].get("href"))
    r = requests.get("http://google.com/", "溜池山王 亀戸 交通費") soup = BeautifulSoup(r.text, 'lxml')
    num_open = min(1, len(link_elems)) for i in range(num_open): webbrowser.open("http://google.com",link_elems[i].get("href"))
    for a in soup.find_all("p"): print(a.text)
     けれども、これを動かしてみると、「©2018‐プライバシー‐規約」しか出てこなかった。完全な失敗である。
     Googleで検索した検索結果の上位1位のサイトから「市ヶ谷⇒飯田橋、渋谷⇒目黒、溜池山王⇒亀戸」の交通費をそれぞれ表示させるつもりで書いたが、根本的なエラーがあるようだ。
     しかし、チャレンジすることが大事である。Pythonについて学び、いつかは完璧な「なまけ者」になりたいと思っている。

    プログラミングを学ぶとどんな未来が待っているのか

     8月12日(日)、座学&実習を通じて、1日でプログラミングの概要をつかむことができる講座『人気Python技術書の著者が教える【正しいプログラミングの学びかた】〜プログラミングで仕事・人生をハックしよう〜』が開催される。講師は、『みんなのPython(SBクリエイティブ刊)』の著者として知られる柴田淳氏だ。
     その柴田氏は「同じ作業を3回続けたら、プログラムで自動化すべき」といっている。では、それができるようになったとして、Pythonを学ぶとどんな将来があるのか。柴田氏は次のように話している。
     『なまけ者』であることは、人生において重要な要素ですね。私自身『ポジティブななまけ者』であることを自認しています。なまける方法を探るために全力を尽くすタイプで、Pythonは『前向きになまける』ための最高のツールと言えます。
     私がそのように「がんばらないためにがんばった」結果どうなったかというと、がんばらないで生活ができるようになってしまいました。Pythonでいろいろなことを自動化していたら、それまでのようにクライアント向けのシステム開発をせずに、そこそこの生活を送れるようになったのです。そこそこの生活とは、具体的には家族四人とわんこ一匹、都内の庭付き一戸建てで暮らせるくらい、です。
     私の場合は家族との時間を大切にしたかったのですが、目標は人それぞれだと思います。なまけることによって、ものごとについてよく考えたり、新しいことに向き合うための時間や心の余裕が生まれます。その余裕をバネに、次のステップを踏み出して、目指す方向に前進してゆけるのです。余裕がないと、人間は成長できません。そして、余裕は意識して生み出す必要があります。
     今は『AIがコモディティ化』した時代です。私のようなエンジニアのはしくれから見ると、坂川さんのような編集者は『一般人』の仲間だと思います。そんな方が「スクレイピングしたい」などと考える現代は、とても面白い時代だと思います。
     AIをはじめとする技術の発達のおかげで、いろいろなことがプログラミングで自動化できる『ちょっと先の未来』を見せてくれるのがPythonというプログラミング言語だと思います。過去二回の講座が、特に非エンジニアの方に好評だったのは、そんな未来について感じ取っていただけたからかも知れないと考えています。
     そして、なんと筆者が書いたコードについて、柴田氏からコメントをいただいてしまった。
     まず、もっと効率よくなまける方法について考えましょう。
     長いプログラムは、正しく動くことを確認するのが大変です。プログラムとして実行したい手順を、もっと細かく分割した方が、作るのも確認するのも楽になります。『上手なプログラミング』とは、『いかになまけるかを考えながら作るプログラミング』に他なりません。
     作っていただいたプログラムを最初から見ながら、動きを確認していきましょう。
     最初の2行は、必要なライブラリーを読み込む「おまじない」の部分ですね。一つ目の問題は4行目です。この行を実行して、戻り値を代入しているrという変数を使って「r.url」のように実際にアクセスが行われるURLを確認すると次のようになります(URLを読みやすいように変換してあります)。
     http://www.google.com/?市ヶ谷%E3%80%80飯田橋%E3%80%80交通費=
     このURLをコピペしてブラウザーで開いてみると,検索結果が表示されていないはずです。実際にGoogleで「市ヶ谷 飯田橋 交通費」を検索して、URLを見ると分かるのですが「/search?q=...」というURLにしないと、検索結果が表示されません。まずはこの点について解決する必要があります。
     5行目では、検索結果のHTMLをスクレイピング用のオブジェクトに変換しています。次の行で、link_elemsという変数の長さを調べています。この変数はプログラムで定義されていないので、エラーになってしまいます。
     この変数には、検索結果のHTMLのうちリンクだけを取り出した結果を入れておけばいいはずです。そのためには、soupという変数に対してfind_all()メソッドを呼び出すなどして、リンクだけを取り出します。ただし、リンクを全部取り出すと、「地図」「ニュース」のようなリンクまで入ってしまうので、少し工夫をする必要があります。
     9行目までを、期待通りに動くように書き換えたプログラムは次のようになります。
    
    
    import requests, sys, webbrowser from bs4 import BeautifulSoup
    # 検索文字列 params={"q":"市ヶ谷 飯田橋 交通費"} # Googleから検索結果を得る r = requests.get("http://google.com/search", params) # HTMLをBeautifulSoupオブジェクトに変換 soup = BeautifulSoup(r.text, 'lxml')
    # 検索結果のURLを保存する変数を,空のリストで初期化 link_elems = []
    # 検索結果のaタグだけを抜き出し,要素でループ for link in soup.find_all('a'): # /url?q=で始まっているリンクだけを抜き出し,リストに追加 if "/url?q=" in link["href"]: link_elems.append(link["href"])
    # 検索結果の最初のリンクをWebブラウザで開く if link_elems: webbrowser.open("http://google.com"+link_elems[0])
     とてもありがたい。こういった質問ができるのも、Python講座の魅力なのだろう
     柴田氏のPython講座は8月12日(日)開催だ。大事なのは、手を動かすことである。猛暑の今年は、クーラーのある部屋でPythonを学ぶのがおすすめ。皆さん、ぜひPythonを始めましょう!

    8月12日開催:講座概要

    • 日時:日時:2018年8月12日(日)10:00 - 19:00(当日9:30受付開始)
    • 会場:角川第3本社ビル(東京都千代田区富士見1-8-19)
    • 対象者:
      • プログラミングを初めて学んでみたい方
      • Pythonを活用した機械学習に興味をお持ちの方
      • 自分に合ったブログラミング学習の方法について悩みをお持ちの方 など
    • 参加費(昼食付):2万7千円(税込)
    • 講師(敬称略):柴田 淳
    • 主催:株式会社角川アスキー総合研究所
    • 詳細情報・ご応募:Peatixページをご覧ください

    0 コメント:

    コメントを投稿