最終投稿日:2022年6月18日
ライブラリ(BeautifulSoup)
スクレイピングによる解析ライブラリ
※Anaconda3 を入れていればあります
基本的な使い方は、HTML 文と、パーサー文字列を引数にインスタンスを生成します。
例)
基本的な使い方は、HTML 文と、パーサー文字列を引数にインスタンスを生成します。
例)
soup = BeautifulSoup(html, 'html.parser')
※HTML 文を解析する場合は「'html.parser'」を使う
※ライブラリ「urllib」の『request.urlopen(url) 』で取得したものを使う(read メソッドは不要)
※HTML 文を解析する場合は「'html.parser'」を使う
※ライブラリ「urllib」の『request.urlopen(url) 』で取得したものを使う(read メソッドは不要)
○ HTML 構造から取得する
v = soup.html.body.h1 ※最初の h1 タグの内容を取得できる
v = soup.html.body.p ※最初の p タグの内容を取得できる
v = soup.html.body.p.next_sibling.next_sibling ※最初の p タグの次の要素を取得できる
v.string で要素内の文字列のみを取得できる(v だけだとタグ付きとなる) 【注意】
v = soup.html.body.p ※最初の p タグの内容を取得できる
v = soup.html.body.p.next_sibling.next_sibling ※最初の p タグの次の要素を取得できる
v.string で要素内の文字列のみを取得できる(v だけだとタグ付きとなる) 【注意】
next_sibling は次の要素を取得するための変数ですが、1つだけ指定すると基本的なサイトの作りとして
改行文字とかになる可能性が高いので、2回記述しています。
なのでサイトの作りが<p>hoge</p><div>foo</div><span>bar</span>と、連続して記述してある場合に
hoge の要素に対して next_sibling を2回記述すると bar が取得されます。
改行文字とかになる可能性が高いので、2回記述しています。
なのでサイトの作りが<p>hoge</p><div>foo</div><span>bar</span>と、連続して記述してある場合に
hoge の要素に対して next_sibling を2回記述すると bar が取得されます。
○ find メソッドから取得する
v = soup.find(id='hoge') ※id 属性 hoge の値を取得する
v = soup.find(class_='hoge') ※class 属性 hoge の値を取得する
v = soup.find('title') ※title タグの値を取得する
v.string v.contents[i] ※多重構造になっている中身を取得できる。例)<span class="important">8,800<small>円</small></span>
上記で【8,800】を取得したい場合、span タグを find し、v.string としても、small タグも内包しているため取得できません。
その様な場合は、v.contents[0] とすると取得できます。
v = soup.find(class_='hoge') ※class 属性 hoge の値を取得する
v = soup.find('title') ※title タグの値を取得する
v.string v.contents[i] ※多重構造になっている中身を取得できる。例)<span class="important">8,800<small>円</small></span>
上記で【8,800】を取得したい場合、span タグを find し、v.string としても、small タグも内包しているため取得できません。
その様な場合は、v.contents[0] とすると取得できます。
○ find_all メソッドから取得する
links = soup.find_all('a') ※リンク等はサイト内に複数あるのでこのメソッドが使えます。
links = soup.find_all("a", class_="link", href="/link") ※classがlinkでhrefが/linkのaタグをすべて取得する
または、
links = soup.find_all("a", attrs={"class": "link", "href": "/link"})
for a in links:
link = a.attrs['href'] ※A タグの href 属性の内容を取得できる(要するにリンク URL)
text = a.string ※A タグの要素を取得できる
tag = a.name ※タグの要素名を取得(DIV とか) 【メモ】
links = soup.find_all("a", class_="link", href="/link") ※classがlinkでhrefが/linkのaタグをすべて取得する
または、
links = soup.find_all("a", attrs={"class": "link", "href": "/link"})
for a in links:
link = a.attrs['href'] ※A タグの href 属性の内容を取得できる(要するにリンク URL)
text = a.string ※A タグの要素を取得できる
tag = a.name ※タグの要素名を取得(DIV とか) 【メモ】
上記の様に a.attrs['href'] で URL を取得できますが、解析元の URL が相対で記述されている場合は、当然相対 URL のまま取得できます。
これを絶対 URL にするには urllib.parse ライブラリの urljoin メソッドを使うと良い。
これを絶対 URL にするには urllib.parse ライブラリの urljoin メソッドを使うと良い。
○ select_one メソッドで CSS セレクタを使い値を1つ取得する
v = soup.select_one('div#meigen > h1') ※id=meigen を持つ div タグ内の h1 タグの値を取得する
v.string
v.string
○ select メソッドで CSS セレクタを使い値を複数取得する
※id=meigen を持つ div タグ内の class=items を持つ ul タグ内の li タグの値を全て取得する
v = soup.select('div#meigen > ul.items > li')
for li in v:
li.string ※ループで各値を取得できる 【メモ】
v = soup.select('div#meigen > ul.items > li')
for li in v:
li.string ※ループで各値を取得できる 【メモ】
セレクタを自動で生成する方法があります。
クロムの場合は F12 で解析画面を表示し、取得したいコード上で右クリックし Copy -> Copy selector を選択します。
以下はペーストしたサンプル
#main > div.stocksDtlWp > div > div.forAddPortfolio > table > tbody > tr > td
上記サンプルをそのままセレクタとして利用できます。
ただし、なぜか tbody が混ざってるとエラーとなってしまったので注意!
上記サンプルでは以下の様に tbody を抜いてエラーを回避しました。
例)
soup.select_one('#main > div.stocksDtlWp > div > div.forAddPortfolio > table > tr > td')
クロムの場合は F12 で解析画面を表示し、取得したいコード上で右クリックし Copy -> Copy selector を選択します。
以下はペーストしたサンプル
#main > div.stocksDtlWp > div > div.forAddPortfolio > table > tbody > tr > td
上記サンプルをそのままセレクタとして利用できます。
ただし、なぜか tbody が混ざってるとエラーとなってしまったので注意!
上記サンプルでは以下の様に tbody を抜いてエラーを回避しました。
例)
soup.select_one('#main > div.stocksDtlWp > div > div.forAddPortfolio > table > tr > td')
○ その他のメソッド(prettify)
値を整形する。
soup = BeautifulSoup(html, 'html.parser')
print(soup.prettify())
上記の様に prettify メソッドを使って表示するとタブ等の間隔も綺麗に表示してくれます
soup = BeautifulSoup(html, 'html.parser')
print(soup.prettify())
上記の様に prettify メソッドを使って表示するとタブ等の間隔も綺麗に表示してくれます
セレクタ表
● セレクタの基本式
| * | 全ての要素 |
| 要素名 | 要素名の要素 例)div |
| .クラス名 | クラス名 |
| #id名 | id名 |
● セレクタ同士の関係を指定する書式
| セレクタ, セレクタ | 列挙された複数のセレクタ 例)h1, h2 |
| セレクタ セレクタ | 下の階層の子孫要素 例)div h1 |
| セレクタ > セレクタ | 直下の階層の子要素 例)div > h1 |
| セレクタ + セレクタ | 同じ階層で直後に隣接している要素 例)h1 + h2 |
| セレクタ1 ~ セレクタ2 | セレクタ1からセレクタ2までの要素 例)p~ul |
● セレクタの属性による指定書式
| 要素[att] | 特定の属性名を持つ要素 |
| 要素[att='val'] | att 属性に val という値を持つ要素 |
| 要素[att~='val'] | att 属性の値候補 val(スペース区切り)に一致した要素 |
| 要素[att | ='val'] | att 属性の値が val で始まる要素(ただしハイフン区切り) |
| 要素[att^='val'] | att 属性の値が val で始まる要素 |
| 要素[att$='val'] | att 属性の値が val で終わる要素 |
| 要素[att*='val'] | att 属性の値を含む要素 |
| 要素:root | ルートとなる要素 |
| 要素:nth-child(n) | n 番目の子となる要素 |
| 要素:nth-last-child(n) | 後ろから n 番目の子となる要素 |
| 要素:nth-of-type(n) | n 番目のその種類の要素 |
| 要素:first-child | 子として最初の要素 |
| 要素:last-child | 子として最後の要素 |
| 要素:first-of-type | 最初のその種類の要素 |
| 要素:last-of-type | 最後のその種類の要素 |
| 要素:only-child | 子として唯一の要素 |
| 要素:only-of-type | 子として唯一の種類の要素 |
| 要素:empty | 要素内容が空となる要素 |
| 要素:lang(code) | 特定の言語に code を指定された要素 |
| 要素:not(s) | s 以外の要素 |
| 要素:enabled | 有効となっている UI 要素 |
| 要素:disabled | 無効となっている UI 要素 |
| 要素:checked | チェックされている UI 要素 |
BeautifulSoup では、nth-child 等のセレクタには対応していません。
その代わり nth-of-type で代用できます。
(おそらく~type となっているのが代用できるセレクタです。。)
その代わり nth-of-type で代用できます。
(おそらく~type となっているのが代用できるセレクタです。。)




