webスクレイピングとやらをやってみたくて、Udemyの講座を受講した。
Pythonによるビジネスに役立つWebスクレイピング(BeautifulSoup、Selenium、Requests)
基礎から丁寧に解説してくれており、実際に手を動かしながらやってみる形式で、演習問題もあり、非常に良質の講座でした。
しかし、いかんせん脳みそが小さいものだから、習った内容が盛りだくさん(普通の人にとっては盛りだくさんではないのかもしれない)で、ごっちゃごちゃに混乱状態になってしまった。
で、整理するための備忘録その2です。
ちなみにpython,webスクレイピングとも超初心者です。
ブラウザはGooGleChrome、コードエディターはjupyterNotebook(Anacondaに入ってたやつ)を使用しています。
1.BeautifulSoupの要素のつかみ方:Select
まず、BeautifulSoupで要素を特定して、要素内のテキストやURLを取得するとき、
select,find,find_allを使うらしい。
実際にやってみて整理してみようと思います。
このようなHTMLを直接読み込んででやってみます。htmlの書いたことなくて見よう見まね。。。
#html
html = """
<html>
<head>
  <meta charset="UTF-8"/>
  <title>testhtml</title>
</head>
<body>
    <h1>おすすめ記事</h1>
    <br>
    <div class="container">
        <div class="itemA">
            <h2 class="excel">エクセル</h2>
                <ul>
                    <li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>
                    <li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>
                </ul>
            </div>
        <br>
        <div class="itemB">
            <h2 class="vba">VBA</h2>
            <ul>
                <li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>
                <li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>
            </ul>
        </div>
        
    </div>
</body>
</html>
"""
#BeautifulSoupをインポートし、変数htmlを解析してsoupに代入
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,"html.parser")(1)soupにはなにが入ったのか。タグを指定して要素を取り出すとはどうゆうことか
soup.body とすると、<body>タグ~そのお尻</body>までが出力されました。
合致したhtml要素のカタマリ(タグの中身)を返すのですね。
soup.body出力結果
<body>
<h1>おすすめ記事</h1>
<br/>
<div class="container">
<div class="itemA">
<h2 class="excel">エクセル</h2>
<ul>
<li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>
<li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>
</ul>
</div>
<br/>
<div class="itemB">
<h2 class="excel">VBA</h2>
<ul>
<li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>
<li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>
</ul>
</div>
</div>
</body>soup.body.h1 とすると、bodyの下の<h1>タグの最初からお尻</h1>まで出力されました。
このようにselectメソッドなどを使わなくても、要素の特定ができれば要素の出力などもできるようですね。
soup.body.h1出力結果
<h1>おすすめ記事</h1>(2)selectメソッド
selectメソッドを使ってみます。
slelctメソッドはCSSセレクタを指定して要素を取り出すそうです。よくわかりませんね。
タグ名で指定してみます。
soup.select(“body”) とすると、上記と同様に<body>タグ~そのお尻</body>までが出力されました。ただし、selectはリストで返ってくるので[]内に入っています。select_oneメソッドだとリスト型ではなく最初の一つだけ返ってきます。
soup.select("body")
#出力結果
[<body>
 <h1>おすすめ記事</h1>
 <br/>
 <div class="container">
 <div class="itemA">
 <h2 class="excel">エクセル</h2>
 <ul>
 <li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>
 <li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>
 </ul>
 </div>
 <br/>
 <div class="itemB">
 <h2 class="vba">VBA</h2>
 <ul>
 <li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>
 <li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>
 </ul>
 </div>
 </div>
 </body>]
#select_one
soup.select_one("body")
#出力結果
<body>
<h1>おすすめ記事</h1>
<br/>
<div class="container">
<div class="itemA">
<h2 class="excel">エクセル</h2>
<ul>
<li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>
<li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>
</ul>
</div>
<br/>
<div class="itemB">
<h2 class="vba">VBA</h2>
<ul>
<li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>
<li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>
</ul>
</div>
</div>
</body>(3)タグで指定する
select(“タグ名”) ダブルクォーテーションかシングルクォーテーションでタグ名を囲んで指定します。
elem = soup.select("li")
elemelemの出力結果:リストにhtml内のli要素4つが入りました。
[<li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>, <li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>, <li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>, <li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>
〇複数タグで指定する
カンマでタグ名を区切って指定します
elem = soup.select("h2,li")
print(elem)出力結果。<h2>タグと<li>タグの内容が出力されました。
[<h2 class="excel">エクセル</h2>, 
<li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>, 
<li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>, 
<h2 class="vba">VBA</h2>, 
<li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>, 
<li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>](4)複数タグを使った指定
〇××タグの下の△△タグの指定
××の直下の△△の指定は > 
divの直下のulの直下のliの指定
elem = soup.select("div > ul > li")
print(elem)××の下の△△の指定は 空白でつなぎます。
divの下のliの指定。こちらは直下でなくてOK。
elem = soup.select("div li")
print(elem)どちらも出力結果は同じです。
(5)検索範囲を狭める
検索範囲を狭める。
上記はhtml全体からヒットするものを検索していました。selectなどで検索範囲を絞り込みすると、目的の要素を取り出しやすくなりそうです。
#elemにクラスitemAのdivタグの中身だけを代入(※1)
elem = soup.select_one("div.itemA")
#その中からliタグを取り出し(※2)
elem_li = elem.select("li")
#取り出したli要素の0番目(※3)
print(elem_li[0])
<li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>
#取り出したli要素の1番目のテキスト
print(elem_li[1].text)
エクセルCOUNTIF高速
#取り出したli要素の1番目のaタグ内のhref属性(※4、5)
print(elem_li[1].a["href"])
https://mwkexcelfriend.com/excel-countif-speedup/※1:divタグのクラスitemA用をelemに代入しました。リスト形式にしたくなかったのでselect_oneを使用しています。
そうすると、elemに<div class=”itemA”>~</div>までが入ります。
<div class=”itemA”> <h2 class=”excel”>エクセル</h2> <ul> <li class=”excel recomend” id=”article1″><a href=”https://mwkexcelfriend.com/excel-vlookup-kousoku/”>エクセルVLOOKUP高速</a></li> <li class=”excel” id=”article2″><a href=”https://mwkexcelfriend.com/excel-countif-speedup/”>エクセルCOUNTIF高速</a></li> </ul> </div>
※2:次はelemから<li>タグを取得してリストに代入します。
リストに2つの要素が入ります。
[<li class=”excel recomend” id=”article1″><a href=”https://mwkexcelfriend.com/excel-vlookup-kousoku/”>エクセルVLOOKUP高速</a></li>,  
<li class=”excel” id=”article2″><a href=”https://mwkexcelfriend.com/excel-countif-speedup/”>エクセルCOUNTIF高速</a></li>]
※3:一つ目を出力します。リストなので[]内にインデックスを指定します。
print(elem_li[0]) 
>出力結果
<li class=”excel recomend” id=”article1″><a href=”https://mwkexcelfriend.com/excel-vlookup-kousoku/”>エクセルVLOOKUP高速</a></li>
※4:2つ名を出力します。
li内のテキストを出力します
print(elem_li[1].text) 
>出力結果
エクセルCOUNTIF高速
※5:li内のaタグ内のhref属性を出力します。il内の<a>なので、.aとつなぎます。そのhref属性なので[“href”]と指定します。
print(elem_li[1].a[“href”]) 
>出力結果
https://mwkexcelfriend.com/excel-countif-speedup/
(6)クラス名で指定する
クラス名は .クラス名 と指定します。
divタグの下のitemAクラスを指定。itemAクラスはhtml内に一つしかないので、この場合はどちらの書き方でも同じ結果となります。
elem = soup.select_one("div.itemA")
elem = soup.select_one(".itemA")出力結果。クラス名itemAを持つdivタグが出力されました。
<div class="itemA">
<h2 class="excel">エクセル</h2>
<ul>
<li class="excel recomend" id="article2"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>
<li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>
</ul>
</div>(7)「××タグの△△クラス」で指定する
<li>タグ内のクラス名recomendを持つ要素
elem = soup.select("li.recomend")出力結果
[<li class="excel recomend" id="article2"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>, <li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>
(8)クラス名を複数指定する方法
●<li>タグ内のクラス名excelとrecomendを両方持つ要素
elem = soup.select("li.excel.recomend")出力結果
[<li class="excel recomend" id="article2"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>]
●クラス名「excel recomend」を持つ要素(完全一致)
elem = soup.select("[class='excel recomend']")出力結果
[<li class="excel recomend" id="article2"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>]●クラスexcelに完全一致する要素
elem = soup.select("[class='excel']")出力結果
[<h2 class="excel">エクセル</h2>,
 <li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>]●クラス名「itemA」または「itemB」を持つ要素
elem = soup.select(".itemA,.itemB")出力結果
[<div class="itemA"> <h2 class="excel">エクセル</h2> <ul> <li class="excel recomend" id="article1"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li> <li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li> </ul> </div>, <div class="itemB"> <h2 class="vba">VBA</h2> <ul> <li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li> <li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li> </ul> </div>]
(9)id名で指定
id名は#で指定します。
<li>タグ内のid名article3
elem = soup.select("li#article3")
elem = soup.select("#article3")この場合、出力結果はおなじ
[<li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>]
(10)idタグを複数使う指定
●id名article2およびarticle4
elem = soup.select("#article3,#article4")出力結果
[<li class="vba recomend" id="article3"><a href="https://mwkexcelfriend.com/excel-vba-transpose-genkai/">TRANCEPOSEちょん切れ</a></li>, <li class="vba" id="article4"><a href="https://mwkexcelfriend.com/excel-vba-hairetu-kousoku/">配列</a></li>]
●クラス名、id名の下のなんちゃらと指定できる
elem = soup.select(".itemA > ul > li")
elem = soup.select(".itemA li")出力結果。どちらも同じ結果
[<li class="excel recomend" id="article2"><a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a></li>, <li class="excel" id="article2"><a href="https://mwkexcelfriend.com/excel-countif-speedup/">エクセルCOUNTIF高速</a></li>]
(11)属性に××を含む
href属性に〇〇を含む
前方一致[href^=’××’] => href=’××://abcd’
後方一致[href$=’××’] => href=’http://abcd××’
あいまい検索[href*=’××’] => href=’http://abcd××efgh’
●href属性に「vlookup」を含む
elem = soup.select("a[href*='vlookup']")出力結果。urlにvlookupを含む<a>タグが出力されました。
[<a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a>]
(12)Copy Selector
Googleの開発者用ツールを使うと、セレクターを教えてくれるようです。
こちらのページを利用してみます。
上記のhtmlを固定ページにしたものです。
https://mwkexcelfriend.com/testtest/

このような内容がコピーされました。id article1の下のa要素ということですね。
#article1 > a
import requests
from bs4 import BeautifulSoup
url = "https://mwkexcelfriend.com/testtest/"
res = requests.get(url)
soup = BeautifulSoup(res.text, "html.parser")
#ここでコピーしたCSSセレクターをselectの引数内に貼り付けする
elem = soup.select("#article1 > a")
#出力
print(elem)
print(elem[0].text)
print(elem[0].attrs["href"])出力結果
print(elem) → 取得した要素そのもの。
print(elem[0].text) → テキストを出力します。
print(elem[0].attrs[“href”]) → href属性を出力します。
リスト形式のため、[0]番目の要素と指定してテキスト、hrefを出力します。
[<a href="https://mwkexcelfriend.com/excel-vlookup-kousoku/">エクセルVLOOKUP高速</a>] エクセルVLOOKUP高速
ごちゃごちゃに書きなぐった。自分の中で整理できたようなできてないような。
勉強させていただいたリンク
わかりやすかった↓
https://gammasoft.jp/blog/difference-find-and-select-in-beautiful-soup-of-python/
こちらも↓
https://lets-hack.tech/programming/languages/python/beautifulsoup/
https://qiita.com/d_m/items/f477c6665ec69dfaf594
https://naruport.com/blog/2019/12/26/bs4-select/
python webスクレイピング 超初心者の備忘録シリーズ

 
  
  
  
  

コメント