HTML コンテンツ運用メモ
Web サーバ設定のために作成したプログラム
動作要件・前提条件
以下の環境が必要である。
- Python 3.x(3.6以降を推奨)
- BeautifulSoup4ライブラリ
Ubuntu では、BeautifulSoup4のインストールは以下のコマンドで行う。
sudo apt install python3-bs4
HTMLファイル複数行置換・一括
#!/usr/bin/env python3
import os
import glob
import tempfile
def read_multiline(prompt):
print(prompt)
lines = []
while True:
try:
line = input()
except EOFError:
break
if line == '---':
break
lines.append(line)
return '\n'.join(lines)
old_text = read_multiline('置換前のテキストを入力(--- で終了):')
new_text = read_multiline('置換後のテキストを入力(--- で終了):')
for filepath in glob.glob('/www/**/*.html', recursive=True):
try:
with open(filepath, encoding='utf-8') as f:
content = f.read()
except UnicodeDecodeError:
print(f'スキップ(UTF-8以外): {filepath}')
continue
if old_text not in content:
continue
stat = os.stat(filepath)
new_content = content.replace(old_text, new_text)
dirpath = os.path.dirname(filepath)
fd, tmp_path = tempfile.mkstemp(dir=dirpath, suffix='.tmp')
try:
with os.fdopen(fd, 'w', encoding='utf-8') as f:
f.write(new_content)
os.replace(tmp_path, filepath)
except:
os.unlink(tmp_path)
raise
os.utime(filepath, (stat.st_atime, stat.st_mtime))
print(f'置換: {filepath}')
headingcheck.py - 見出し構造チェッカー
コマンドライン引数で指定したURLのWebページ内のh1〜h6タグを検査し、階層構造の問題(h1の重複、階層の飛び等)を報告する。
headingcheck.py というファイル名で保存
# -*- coding: utf-8 -*-
import sys
import urllib.request
from bs4 import BeautifulSoup
url = sys.argv[1]
html = urllib.request.urlopen(url)
soup = BeautifulSoup(html, "html.parser")
headings = soup.find_all(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'])
h1_count = 0
prev_level = 0
for h in headings:
level = int(h.name[1])
text = h.get_text().strip()[:30]
if level == 1:
h1_count += 1
if h1_count > 1:
print('NG: h1が複数存在:', text)
if prev_level > 0 and level > prev_level + 1:
print('NG: 階層の飛び h' + str(prev_level) + '→h' + str(level) + ':', text)
prev_level = level
if h1_count == 0:
print('NG: h1が存在しない')
使用例
コマンドラインから以下のように実行する。
python headingcheck.py https://www.example.com/page.html
実行結果の例(見出し構造に問題がある場合):
NG: 階層の飛び h1→h3: 機能の詳細説明
NG: h1が複数存在: もう一つのタイトル
見出し構造に問題がない場合は何も出力されない。
imgcheck.py - 画像参照チェッカー
コマンドライン引数で指定したURLのWebページ内の全imgタグを検査し、参照先の画像ファイルが存在しない場合にエラーを報告する。
imgcheck.py というファイル名で保存
# -*- coding: utf-8 -*-
import sys
import urllib.request
from bs4 import BeautifulSoup
from urllib.parse import urljoin
url = sys.argv[1]
html = urllib.request.urlopen(url)
soup = BeautifulSoup(html, "html.parser")
for img in soup.find_all('img'):
src = img.get('src')
if src is None:
continue
img_url = urljoin(url, src)
try:
urllib.request.urlopen(img_url)
except:
print('NG:', url, img_url)
使用例
コマンドラインから以下のように実行する。
python imgcheck.py https://www.example.com/page.html
実行結果の例(画像参照エラーがある場合):
NG: https://www.example.com/page.html https://www.example.com/images/missing.jpg
NG: https://www.example.com/page.html https://www.example.com/images/deleted.png
画像参照エラーがない場合は何も出力されない。
title.py - Webページタイトル取得プログラム
コマンドライン引数で指定したURLのWebページからタイトル(<title>タグの内容)を取得し、標準出力に表示する。タイトルが存在しない場合や空の場合は、デフォルト値として「金子邦彦研究室」を出力する。
title.py というファイル名で保存
# -*- coding: utf-8 -*-
import sys
import urllib.request
from bs4 import BeautifulSoup
url = sys.argv[1]
html = urllib.request.urlopen(url)
soup = BeautifulSoup(html, "html.parser")
if soup.title is None:
print('金子邦彦研究室')
elif soup.title.string is None or len(soup.title.string) == 0:
print('金子邦彦研究室')
else:
print(soup.title.string.strip())
使用例
コマンドラインから以下のように実行する。
python title.py https://www.example.com/
実行結果の例:
Example Domain
テスト実行
以下のシェルスクリプトにより、ディレクトリ内の全HTMLファイルに対してtitle.pyを実行できる。
for i in */*.html; do
python /tmp/title.py https://www.kkaneko.jp/$i
done
desc.py - メタディスクリプション取得プログラム
コマンドライン引数で指定したURLのWebページから、meta name="description" タグのcontent属性値を取得し、標準出力に表示する。該当するmetaタグが存在しない場合は「Empty」を出力する。
desc.py というファイル名で保存
# -*- coding: utf-8 -*-
import sys
import urllib.request
from bs4 import BeautifulSoup
url = sys.argv[1]
html = urllib.request.urlopen(url)
soup = BeautifulSoup(html, "html.parser")
a = soup.find_all('meta', attrs={'name': 'description'})
if a is None or len(a) == 0:
print('Empty')
else:
for i in a:
c = i.get('content')
if c is None or len(c.strip()) == 0:
print('Empty')
else:
print(c.strip())
使用例
コマンドラインから以下のように実行する。
python desc.py https://www.example.com/
実行結果の例(metaタグにdescriptionが設定されている場合):
This domain is for use in illustrative examples in documents.
実行結果の例(metaタグにdescriptionが設定されていない場合):
Empty