Python - ウェブスクレイピング - BeautifulSoup

 クラウディア
1. 概要
2. インストール
3. 書いてみる
4. meta の要素を取得する
5. タグ・クラスで絞り込み
6. 特定のタグを取り除く

1. 概要

 あるサイトで
日本気象協会 tenki.jp【公式】 / 天気・地震・台風
「日本気象協会 tenki.jp【公式】 / 天気・地震・台風」」

 こんなんから、枠内の地域名のみを取得したいという課題がありましてな・・・。

 「BeautifulSoup」ちゅうのを使うのがいいらしい。

 「Beautiful」と自分で言うちょるんじゃから、ええんじゃろう。
 どうでもいい話ですが、何故、「BeautifulSoup」という名前なのか?
 その答えらしきものは、「Python:webスクレイピングの基礎 │ webのお仕事」に記載されていますが、結局これを読んでもよくわからない。

 由来はともかく、「.html」ファイルのパーサです。

 本項は、下記のサイトを参考にさせていただきました。

Pythonのスクレイピング」
「【Python】BeautifulSoupの使い方・基本メソッド一覧|スクレイピング

2. インストール

 「FreeBSD」に「ports」でインストールできそうです。

$ whereis py-beautifulsoup
py-beautifulsoup: /usr/ports/www/py-beautifulsoup
 インストールします。

cd /usr/ports/www/py-beautifulsoup
make
make install
 オプションは、「DOC」のみです。  「pip」でインストールする場合は。  「root」ユーザ権限で。

pip install bs4
 「bs4」は、「BeautifulSoup4」なのかしら?

3. 書いてみる

 課題を書いてみます。

from urllib import request
from bs4 import BeautifulSoup

html = request.urlopen('https://tenki.jp/')
soup = BeautifulSoup(html, "html.parser")
names = soup.select(".forecast-map-entry")

for name in names:
    for span in name.find_all("span"):
        span.extract()

    print(name.getText())
 これを実行すると

札幌
釧路
仙台
新潟
東京
金沢
名古屋
大阪
高知
広島
福岡
鹿児島
那覇
 なんだか、思い通りに動いてくれました。  一応、解説しておきます(と言いつつ、実はまだ自分でよく理解していない)。  先頭の 2 行の「import」の仕方は、真似しただけなので、よくわかっていません。  4~6行は、オープンして、「BeautifulSoup」で解析、目的のものが「.forecast-map-entry」という「class」(あれ?「id」かも)に所属しているので、抽出してリストにしています。  8~12行で、リストしたものを抽出するのですが、地域名以外のものが含まれています。  「span」で囲まれているので、「span」で囲まれているものを除外すると、地域名だけが残ります。

4. meta の要素を取得する

 わたしのサイトでは、コンテンツの内容を

<html>
<head>

・・・	略	・・・

<meta name="date" content="2021-06-24T10:25:32+0900">
<meta charset="UTF-8">

・・・	略	・・・

<title>タイトル</title>
</head>
<body>

・・・	略	・・・

</body>
</html>
 てな感じで記述して、コンテンツファイルの更新日時を

<meta name="date" content="2021-06-24T10:25:32+0900">
 と記述しております。  この更新日時の部分が欲しくなりましてな。  掲載の参考サイトを元に書いてみました。

import ssl

from urllib import request
from bs4 import BeautifulSoup

ssl._create_default_https_context = ssl._create_unverified_context

try:
  html = request.urlopen('https://freebsd.sing.ne.jp/lang/python/')
  soup = BeautifulSoup(html, 'html.parser')

  head = soup.find('head')

  meta = head.find('meta', {'name' : 'date'})
  date = meta['content']
  print(date)

except Exception as ex:
  import pdb; pdb.set_trace()
 これを実行すると、下記のような結果が得られます(日時なので、動かしたときにより変化しますわな)。

2024-10-18T11:38:07+0900
 詳細な解説はしません。  実は、このページ、実際にこのプログラムを動かしたりしていました。  で、ターゲットをこのページにしたら、自縄自縛に陥っちゃって、返ってこなくなっちゃいました(笑)。

5. タグ・クラスで絞り込み

 ある特定のタグを絞り込んで、抽出するのに、例えは、リンクの「<a>」を抽出するには

soup.find('a')
 てな書き方をします。  すべての「<a>」を抽出するには

soup.findAll('a')
 と書きます。  また、本サイトでは「<pre>」を多用しております。  上記のソースコードをハイライトさせている部分は「<pre class="bare"><code class="language-python">」てな風に書いております。  この部分を抽出する場合、「<pre>」タグの他に「class="bare"」でも絞り込みをしないと、他の部分までとってきてしまいます。  クラス名までつけて、抽出するには

soup.findAll('pre', attrs='bare')
 という書き方をします。

6. 特定のタグを取り除く

 前項で、抽出したタグを取り除くには、「decompose」というメソッドを使用します。

for tag in soup.findAll('pre', attrs=’bare’):
  tag.decompose()
 てな書き方をすると、抽出したものを元のオブジェクトから取り除くことができます。
earthcar(アースカー)
薬屋の独り言
ネットオークションの相場、統計、価格比較といえばオークファン