2021/04/06
[Python]BeautifulSoup4でhtmlの解析
概要
特定のURLを入力値にとり、そのURLのHTMLコンテンツを取得し、タイトル・説明文・アイコン画像のURLなどを取得したかったため実装しました。
beautifulsoup4というものを利用させてもらいました。
実装
インストール
% poetry add beautifulsoup4
# 4.9.3をインストールして使用しました
実装内容
import requests
from bs4 import BeautifulSoup
url = "https://stackoverflow.com/questions/24688479/size-of-raw-response-in-bytes/24688721"
# see https://stackoverflow.com/questions/24688479/size-of-raw-response-in-bytes/24688721
with requests.get(url=url, stream=True) as response:  # 一気に取得すると大きいサイズのものだと困るので、 steam=True としてコンテンツを取得します。
    if response.status_code != 200:
        return False
    if "text/html;" not in response.headers.get("Content-Type"):  # htmlじゃないコンテンツは弾きます。(動画とか画像とか)
        return False
    size = 0
    content_bytes = bytearray(b'')
    for chunk in response.iter_content(8196):                     # 8196バイト毎に読み込みます。
        size += len(chunk)
        if size > 10 * 1024 * 1024:                               # 一定サイズを超えていたら、処理を終了します。今回は10MB
            # the content is too large to continue...
            return False
        content_bytes.extend(chunk)
    encoding = response.encoding if response.encoding else response.apparent_encoding
    text = str(content_bytes, encoding, errors='replace')
    soup = BeautifulSoup(text, features="html.parser")
    # headタグの中身を取得
    title = None
    description = None
    head_info = soup.find("head")
    if head_info:
        meta_title = head_info.find("title")
        if meta_title:
            title = meta_title.getText()
        meta_description = head_info.find("meta", {"name": "description"})
        if meta_description:
            description = meta_description["content"]
    
    print(title)
    print(description)
ポイント
- コンテンツは一気に取得せず、chunksize毎に読み込み、大きいコンテンツの場合は無視します。
- URLの中身が悪質なもの(ウィルスの入ったファイル)の可能性もあるので、考慮すべきです。(もしダウンロードして保存したり実行する場合などは特に)
- このコードを応用すれば、画像ファイルだったら圧縮して保存とかもできそうです。
以上です。
関連する記事

[Python]ハイフンなし電話番号からハイフン付きに復元
Pythonでハイフンなしの日本の電話番号をハイフン付きのものに変換する

[Python]BeautifulSoup4でhtmlの解析
BeautifulSoup4というPythonのライブラリを使って、特定のURLのコンテンツを取得し、タイトルや説明文を取得できるようにしました。

[Python]銀行コードと支店コードの取扱
Pythonで銀行コード、支店コードデータを取り扱う便利なライブラリzengin-codeを導入しました。

Sendgridを使ってメールの受信を行う
Inbound Email Parse Webhookという機能を利用してメールを受信したらWebhookを呼び出すようにしました
