こんなんから、枠内の地域名のみを取得したいという課題がありましてな・・・。
「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()
てな書き方をすると、抽出したものを元のオブジェクトから取り除くことができます。