soup =
BeautifulSoup(html, '
html.parser')
※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 だけだとタグ付きとなる)
【注意】
next_sibling は次の要素を取得するための変数ですが、1つだけ指定すると基本的なサイトの作りとして
改行文字とかになる可能性が高いので、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] とすると取得できます。
○ 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 とか)
【メモ】
上記の様に a.attrs['href'] で URL を取得できますが、解析元の URL が相対で記述されている場合は、当然相対 URL のまま取得できます。
これを絶対 URL にするには urllib.parse ライブラリの urljoin メソッドを使うと良い。
○ select_one メソッドで CSS セレクタを使い値を1つ取得する
v = soup.select_one('div#meigen > h1') ※id=meigen を持つ div タグ内の h1 タグの値を取得する
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 ※ループで各値を取得できる
【メモ】
セレクタを自動で生成する方法があります。
クロムの場合は 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 メソッドを使って表示するとタブ等の間隔も綺麗に表示してくれます