【Python】Webの子育て情報をスクレイピングしたい BeautifulsoupとString操作 【サンプル】

Python 66

ルート66は有名だけど、こだいらあたりでCivicTechでは66歳から始めるPythonが流行っていまして。。Python 66と呼ばれています(いや。。今、この言葉、作ったところだけど(笑)

こないだから。。勉強会をしたりして。。

【Python】プログラミングの最初の第一歩。。Google ColabでPythonはじめよう!【連載になるか?】
プログラミング事始め Microsoft ExcelについているVBAも、Google SpreadSheetについているGoogle A...
報告と次の始まり:海老名66歳はPythonを理解するかPart1
【こんなこと】海老名はPythonを理解するかPart1、66歳の手習い後の宿題が完了しました。 参考になるかのリンク 2019/10/...

Python 66が増えるのか?実験中(笑)

ちなみに、このページのPythonに関する情報は、こちら

で。。。

宿題

本人がやりたいことをするのが、一番でして。。その手助けおば。。Facebook Groupの方で。。

海老名 要一
どうも目指す情報はここに書いてあるらしい この技はネットでググって覚えた

と書いて。。Google Colabのファイルを共有されました(笑)

海老名さんはいろいろ勉強されていて、BeautifulSoupというPythonのスクレイピング用のモジュールを使うのはだいたいできるようになっています。凄い!!

そこの1カラム目に、だいたいしたそうなことをしたスクリプトを書き込んだのですが。。

どういうところに疑問あるのかな? って思って、少し注釈をここに書いてみます

全部のプログラムはこれくらいの量です。全体像はこんな感じです。

# きららのweb情報を入手する
# とみながの方法 サンプル  

import requests
from bs4 import BeautifulSoup

# Webページを取得して解析する
load_url = "https://blog.goo.ne.jp/kirara_kodaira/"
load_urlo="https://blog.goo.ne.jp"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")
alists=soup.find_all('a')
for alist in alists:
 if str(alist).find("子育て広場の予定")!=-1:
  #print(str(alist).find("子育て広場の予定"))
  #print(alist)
  st=int(str(alist).find("/kirara_kodaira/"))
  sp=int(str(alist).find('">'))
  #print(alist[int(str(alist).find("/kirara_kodaira/"))::int(str(alist).find('">'))])
  #print(str(alist)[st:sp])
  load_url_a=str(alist)[st:sp]
  load_url_yotei=load_urlo+load_url_a
  #print(load_url_yotei)
#
# 子育て広場の予定をBSで取得
# 月の予定 を検索して、それに合致したところのURLを取得
html = requests.get(load_url_yotei)
soup = BeautifulSoup(html.content, "html.parser")
alists=soup.find_all('a')
for alist in alists:
   if str(alist).find("月の予定")!=-1:
     #print(alist)
     url1=alist.get("href")
     month_name = alist.get_text()
     #print(url1,month_name)
     break
#最新の1個で止める
#
#次は最新の予定のURLに行ってテキストを取ってくる
html = requests.get(url1)
soup = BeautifulSoup(html.content, "html.parser")
alists=soup.find(class_="entry-body-text").find_all("p")
i=0
for alist in alists:
 print(i,alist.text)
 #print(i,alist)
 i=i+1

実行すると 欲しいところの文章が取れると思います。

0 白梅(きらら広場) 1日(火)11:00~12:30 場所が戻りました!白梅学園大学J棟ホール 自由遊び&誕生会&わらべうた、広いホールで走り回れます。 
1 ベビー三小 17日(木)10:00~11:45、第一会議室 お茶を飲んでホッとひと息する時間があります。 
2 18日(金)ベビー中央 10:00~12:00 中央公民館 和室つつじ 今月は、第3金曜日です。 和室のお部屋で、あかちゃんと、いっしょに、おしゃべりしましょう。出入り自由です。 
3  29日(火)だっこ 10:00〜12:00 中野産婦人科医院ホール(津田町) 大きな窓の明るい部屋の中、おもちゃ・わらべ唄で遊びましょう。 
4 29日(火)はなこ 10:00~12:00 鈴木公民館 和室 わらべ歌、大型絵本読み聞かせ。  
5 きらら毎月イベント  
6  絵本と育ばなちょこっとわらべうた  
7 4日(金)10:30~12:00 きらら事務所 
8  読み聞かせ&おしゃべり。親子でのんびり過ごしましょう! 
9 参加無料、出入りも自由です。 
10  ベビー☆ママのふれあい体操 
11  0歳~1歳前後の赤ちゃんとママのふれあいの場です。 
12 31日(木) 大沼公民館・和室 
13 (受付10:15~) 
14   10:30~11:00 体操 
15   11:00~11:45 おしゃべりタイム  
16 ・参加費 100円・持ち物 バスタオル ・予約はいりません。予防接種直後はご遠慮ください。 
17       
18

その1 スクレイピングの段取りを考える

プログラムにするってことは、何回もやることを、自動的にしちゃうってことで、メンドクサイことを、Pythonにやらせよう!ってことです(笑)

ということで、最終的には、↑の写真にあるように、10月の予定のところのテキストを取得したいってことでしょうけど、そこへ行くまでの動線を考える。。ってところが必要かな?と。。

①トップページに行く

=>https://blog.goo.ne.jp/kirara_kodaira/ にアクセスですね。

そうすると、どこを見たらいいか??を考えます。このブログには、カテゴリーっていうのがあって、どうやら。。

子育て広場の予定

っていうのがあります。そこのURLを取ってきてアクセスすると、予定が入ってそうです。

では、実際に子育て広場の予定に行ってみます

②10月の予定 とか。。9月の予定とか 。。 タイトルの法則性を見つけます

子育て広場の予定 で取ってきたい本文が含まれている記事は、きららの広場 10月の予定 とか きららの広場 9月の予定 とかになっています。

月の予定 を取ってくればいい。それの一番新しいURLを取得するといい。

③月の予定から 必要な文字を取ってくる

ここまでくれば、あとは、HTMLのソースコードを見てとってくればいいと思います。

って感じのストーリというか、順番をまず考えるんですよね。

それぞれのコード

RequestsとBeasutifulsoup

Resuests は こちらのページを参照

Requests: 人間のためのHTTP — requests-docs-ja 1.0.4 documentation

Beasutifulsoup は 本家は

Beautiful Soup Documentation — Beautiful Soup 4.12.0 documentation

Beautifulsoupの基本的な使い方は、ここがよくまとまっていると思います。

【Python】BeautifulSoupの使い方・基本メソッド一覧|スクレイピング | Let's Hack Tech
Pythonを使ったWebスクレイピングの比較的メジャーなライブラリBeautifulSoupのメソッドを一挙紹介します。 このページを読めばBeautifulSoupのほとんどの動作、メソッドを確認することができます。 以下の目次は展開で

で、この構文は、覚えるしかないです(笑) というか。。僕は覚えてないので、いつもググってます(笑)

import requests
from bs4 import BeautifulSoup

load_url = "https://blog.goo.ne.jp/kirara_kodaira/"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

ここまでは、おまじないとして覚えるってのも手ですが(笑) 単純に、load_urlを読み込んで、BeautifulSoupでパースするだけです。これ何度も出てきますので。。

トップページから、子育て広場の予定のURLを取得

さて、soupの中に、情報が入っています。そこから、HTMLの構文 a  リンクが書かれているところを抜き出してきます。 soup.find(‘なんとか’)だと最初の1個目、.find_all(‘なんとか’)だと全部。

HTMLの構文 a というのは、<a href=”URLが入ってる”>表示される文字</a> ってなっているところです。

alists=soup.find_all('a')

これをalistsという変数に代入します。

そして、for alist in alists で alistsを 一行づつに分解します。

if str(alist).find("子育て広場の予定")!=-1:

ってところは、alistをstr()でくくっているのは、文字列に変換しています。.find()メソッドで、文字列を検索しています。この.find()は、文字があったら、その文字の位置が返ってきます。もし文字がなかったら、-1が返ってきます。

alistの文字の中に、”子育て広場の予定”が ある場合 って意味になります。

コメントアウトしてありますが、print(alist) を見てみると、子育て広場の予定が入っているものが出力されます。

<a href="/kirara_kodaira/c/71125a8f4f055a9c541fcee7ec6ffe57"><span class="mod-cat-name">子育て広場の予定</span></a>

その中でURLを簡単に拾ってこれればいいのです。 この文字列から、赤字のところを取ってくればURLを作れそうですね。

取り方は、↑のstr().find()を使って/kirara_kodaira/ と ”> の位置をとってきます。

st=int(str(alist).find("/kirara_kodaira/"))
sp=int(str(alist).find('">'))

そして。。 今度は、文字列のスライスという機能で、alistの/kirara_kodaira/の位置から、”>の位置までとってくる ってことをしています。

load_url_a=str(alist)[st:sp]

このあたりのことは、第一回勉強会で使ったノートのスライシングを見てください(Githubの場合はこちら)たぶん、最初にこのあたりは、やはり勉強必要ですね。

これでURLはできました。

子育て広場の予定 から 月の予定を取ってくる

今度は、月の予定です。上とほぼ同じですが、今度は

url1=alist.get("href")

と、違う方法でURLを取ってきています。url1=alist.a.get(“href”) でもいいんですが。。その前で、a タグだけを取ってきているので省略しています。

beautifulsoupはこのaタグについては、いろいろできるようになっています。なぜかっていうと、リンクが入っているので、そのリンクの先を取得したいってことが、スクレイピングの主なやり方だからですね。

あとは、ほぼ上と同じです。

これで、最新月の予定のURLが出てきました。

月の予定から 必要な文字を取ってくる

ここまでくれば、ほぼ。。できたようなものです。最新月の予定のURLにアクセスして、ソースを見て、取ってきたい部分を見てみると、

<!-- entry-body -->
<div class="entry-body">
<div class="entry-body-text"><h3><img src="https://blogimg.goo.ne.jp/img_emoji/m_0024.gif"> 10月の きらら広場の予定 <img src="https://blogimg.goo.ne.jp/img_emoji/m_0025.gif"></h3>
<div class="entry-body">
<div class="entry-body-text">
<p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0237.gif">白梅(きらら広場)<br /> 1日(火)11:00~12:30<br /> 場所が戻りました!白梅学園大学J棟ホール<br /> 自由遊び&誕生会&わらべうた、広いホールで走り回れます。</p>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/hamster_1.gif"><span>ベビー三小</span><br /><span> 17日(木)10:00~11:45、第一会議室</span><br /><span> お茶を飲んでホッとひと息する時間があります。</span></p>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/hiyo_eye.gif">18日(金)ベビー中央 10:00~12:00<br /> 中央公民館 和室つつじ<br /> 今月は、第3金曜日です。<br /> 和室のお部屋で、あかちゃんと、いっしょに、おしゃべりしましょう。出入り自由です。</p>
<p align="left">&nbsp;<img src="https://blogimg.goo.ne.jp/img_emoji/m_0235.gif">29日(火)だっこ 10:00〜12:00<br /> 中野産婦人科医院ホール(津田町)<br /> 大きな窓の明るい部屋の中、おもちゃ・わらべ唄で遊びましょう。</p>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/hawaii_plumeria.gif">29日(火)はなこ 10:00~12:00<br /> 鈴木公民館 和室<br /> わらべ歌、大型絵本読み聞かせ。<br /> </p>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>
<div><img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif">        </div>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0234.gif">きらら毎月イベント&nbsp;<img src="https://blogimg.goo.ne.jp/img_emoji/m_0234.gif"></p>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0070.gif">&nbsp;絵本と育ばな<img src="https://blogimg.goo.ne.jp/img_emoji/m_0146.gif">ちょこっとわらべうた </p>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0213.gif">4日(金)10:30~12:00 きらら事務所</p>
<p>&nbsp;読み聞かせ&おしゃべり。親子でのんびり過ごしましょう!</p>
<p>参加無料、出入りも自由です。<img src="https://blogimg.goo.ne.jp/img_emoji/hearts_pink.gif"></p>
<div>&nbsp;</div>
</div>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/hiyob_uru.gif">&nbsp;ベビー☆ママのふれあい体操<img src="https://blogimg.goo.ne.jp/img_emoji/hiyob_en.gif"></p>
<p>&nbsp;0歳~1歳前後の赤ちゃんとママのふれあいの場です。</p>
<p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0244.gif">31日(木) 大沼公民館・和室</p>
<p>(受付10:15~)</p>
<p>  10:30~11:00 体操</p>
<p>  11:00~11:45 おしゃべりタイム </p>
<p>・参加費 100円<br /><br />・持ち物 バスタオル <br /><br />・予約はいりません。<img src="https://blogimg.goo.ne.jp/img_emoji/m_0220.gif">予防接種直後はご遠慮ください。</p>
<p>&nbsp;<img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"></p>
<p>  &nbsp;</p>
</div>
</div>

どうも、<div class=”entry-body-text”> の<p>の部分に必要な情報がありそうです。これを、取ってくるには

alists=soup.find(class_="entry-body-text").find_all("p")

ってしています。この中から、テキストだけを抜いてきています。

alist.text ってしているだけですね。 上のような出力になります。

ここからは、自分で。。

さて、ここまで行きましたが、これ、2つの種類のイベントを入れているみたいです。そして、アイコンが区切りの役目をはたすようにして、使われています。

ちょっとソースそのままを出力してみると。。

0 <p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0237.gif"/>白梅(きらら広場)<br/> 1日(火)11:00~12:30<br/> 場所が戻りました!白梅学園大学J棟ホール<br/> 自由遊び&amp;誕生会&amp;わらべうた、広いホールで走り回れます。</p>
1 <p><img src="https://blogimg.goo.ne.jp/img_emoji/hamster_1.gif"/><span>ベビー三小</span><br/><span> 17日(木)10:00~11:45、第一会議室</span><br/><span> お茶を飲んでホッとひと息する時間があります。</span></p>
2 <p><img src="https://blogimg.goo.ne.jp/img_emoji/hiyo_eye.gif"/>18日(金)ベビー中央 10:00~12:00<br/> 中央公民館 和室つつじ<br/> 今月は、第3金曜日です。<br/> 和室のお部屋で、あかちゃんと、いっしょに、おしゃべりしましょう。出入り自由です。</p>
3 <p align="left"> <img src="https://blogimg.goo.ne.jp/img_emoji/m_0235.gif"/>29日(火)だっこ 10:00〜12:00<br/> 中野産婦人科医院ホール(津田町)<br/> 大きな窓の明るい部屋の中、おもちゃ・わらべ唄で遊びましょう。</p>
4 <p><img src="https://blogimg.goo.ne.jp/img_emoji/hawaii_plumeria.gif"/>29日(火)はなこ 10:00~12:00<br/> 鈴木公民館 和室<br/> わらべ歌、大型絵本読み聞かせ。<br/> </p>
5 <p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0234.gif"/>きらら毎月イベント <img src="https://blogimg.goo.ne.jp/img_emoji/m_0234.gif"/></p>
6 <p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0070.gif"/> 絵本と育ばな<img src="https://blogimg.goo.ne.jp/img_emoji/m_0146.gif"/>ちょこっとわらべうた </p>
7 <p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0213.gif"/>4日(金)10:30~12:00 きらら事務所</p>
8 <p> 読み聞かせ&おしゃべり。親子でのんびり過ごしましょう!</p>
9 <p>参加無料、出入りも自由です。<img src="https://blogimg.goo.ne.jp/img_emoji/hearts_pink.gif"/></p>
10 <p><img src="https://blogimg.goo.ne.jp/img_emoji/hiyob_uru.gif"/> ベビー☆ママのふれあい体操<img src="https://blogimg.goo.ne.jp/img_emoji/hiyob_en.gif"/></p>
11 <p> 0歳~1歳前後の赤ちゃんとママのふれあいの場です。</p>
12 <p><img src="https://blogimg.goo.ne.jp/img_emoji/m_0244.gif"/>31日(木) 大沼公民館・和室</p>
13 <p>(受付10:15~)</p>
14 <p>  10:30~11:00 体操</p>
15 <p>  11:00~11:45 おしゃべりタイム </p>
16 <p>・参加費 100円<br/><br/>・持ち物 バスタオル <br/><br/>・予約はいりません。<img src="https://blogimg.goo.ne.jp/img_emoji/m_0220.gif"/>予防接種直後はご遠慮ください。</p>
17 <p> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"/> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"/> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"/> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"/> <img src="https://blogimg.goo.ne.jp/img_emoji/clover.gif"/></p>
18 <p>   </p>
もし、ここから予定表を作成しようと、すると。。 この人の文章の特徴を利用する。
上の行番号0から4までは、1行でイベント内容がまとまっています。
なので、例えば、「きらら毎月イベント」までは、1行ごとにイベントとして、日 時間 場所を取ってくるようにスライスする。
それ以降は、<p><img src=” という文字がなんとなく、イベントの最初(区切り)を示しているよう。その言葉の間にあるものを一塊にすると、一個のイベント情報になる。と思います。

もう文字列での操作もできるので、これをもう一歩、表形式にしたり、イベントの日、時間、場所 内容をそれぞれに入れることも出来そうですね!

がんばれ!! NotebookのソースはGithubに入れておきました。