[streamlit×python]複数Qiita記事サムネイル抽出Webアプリを作成してみた



# はじめに
Qiitaをご覧の皆さん、こんにちは！

今回は、**StreamlitとPythonを使って、複数のQiita記事のサムネイル画像を抽出するWebアプリ**を作成しました。普段Qiitaの記事を読んでいる中で、「この記事のサムネイル、どんなデザインなんだろう？」とか、「まとめてサムネイルを見たいな」と思ったことはありませんか？そんな思いを形にすべく、個人的な学習も兼ねて開発してみました。

この記事では、開発したアプリの概要、使用したツール、そして具体的なコード解説までを詳しくご紹介します。ぜひ最後までお読みいただき、皆さんの開発の一助となれば幸いです！

---

# 使用したツール
今回のWebアプリ開発で使用した主なツールは以下の通りです。

* **Python**: プログラミング言語
* **Streamlit**: PythonでWebアプリを簡単に作成できるフレームワーク
* **requests**: HTTPリクエストを送信するためのライブラリ
* **Beautiful Soup**: HTMLやXMLファイルを解析するためのライブラリ

---

# 実際に出来上がったもの
実際に開発したWebアプリはこちらです。

**Webアプリ**:


https://qiitathumbnailapp-gzypbkvjdpjskir6siwv5p.streamlit.app/

**GitHubリポジトリ**:


https://github.com/kousei6/qiita_thumbnail_app?tab=readme-ov-

アプリにQiita記事のURLを入力すると、その記事のサムネイル画像が表示されます。複数のURLを改行区切りで入力することも可能です。ぜひ触ってみてください！

---

# コード解説
それでは、主要なコードについて解説していきます。

まず、必要なライブラリをインポートします。

```python
import streamlit as st
import requests
from bs4 import BeautifulSoup
```

次に、Qiita記事のURLからサムネイル画像を抽出する関数を定義します。

```python
def get_qiita_thumbnail(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # HTTPエラーがあれば例外を発生させる
        soup = BeautifulSoup(response.text, 'html.parser')

        # og:image メタタグを探す
        og_image_tag = soup.find('meta', property='og:image')
        if og_image_tag and og_image_tag.get('content'):
            return og_image_tag['content']
        else:
            # og:imageが見つからない場合、代替のセレクタや直接的な画像URLを探す処理を追加することも検討
            # 例: 特定のdivやimgタグを探す
            # return None
            return "サムネイルが見つかりませんでした。" # よりユーザーフレンドリーなメッセージ

    except requests.exceptions.RequestException as e:
        return f"URLへのアクセス中にエラーが発生しました: {e}"
    except Exception as e:
        return f"サムネイル抽出中にエラーが発生しました: {e}"
```
`get_qiita_thumbnail`関数では、以下の処理を行っています。
1.  `requests.get(url)`で指定されたURLからHTMLを取得します。
2.  `BeautifulSoup`を使ってHTMLを解析します。
3.  `og:image`プロパティを持つ`meta`タグを探し、その`content`属性（サムネイル画像のURL）を取得します。
4.  エラーハンドリングを行い、URLへのアクセスエラーやその他のエラーが発生した場合に適切なメッセージを返します。

次に、Streamlitアプリケーションのレイアウトとロジックを記述します。

```python
st.set_page_config(
    page_title="Qiita記事サムネイル抽出アプリ",
    page_icon="🖼️",
    layout="centered",
    initial_sidebar_state="auto",
)

st.title("🖼️ Qiita記事サムネイル抽出Webアプリ")
st.markdown("複数のQiita記事のサムネイル画像を抽出します。")

# 説明を追加
st.info("Qiita記事のURLを1行に1つずつ入力してください。")

# テキストエリアでURLを入力
urls_input = st.text_area("Qiita記事のURLを入力してください（複数ある場合は改行）", height=150)

if st.button("サムネイルを抽出"):
    if urls_input:
        urls = [url.strip() for url in urls_input.split('\n') if url.strip()]
        if not urls:
            st.warning("URLが入力されていません。")
        else:
            st.subheader("抽出結果")
            for url in urls:
                st.markdown(f"#### 記事URL: {url}")
                thumbnail_url = get_qiita_thumbnail(url)
                if thumbnail_url and "http" in thumbnail_url: # 有効なURLであることを確認
                    st.image(thumbnail_url, caption=f"サムネイル画像 for {url}", use_column_width=True)
                else:
                    st.error(thumbnail_url) # エラーメッセージを表示
                st.markdown("---")
    else:
        st.warning("URLを入力してください。")
```

Streamlitのコードでは、以下のことを行っています。

1.  `st.set_page_config`でページのタイトルやアイコン、レイアウトを設定します。
2.  `st.title`と`st.markdown`でアプリのタイトルと説明を表示します。
3.  `st.text_area`を使って、ユーザーがQiita記事のURLを入力できるテキストエリアを配置します。複数行入力できるように`height`を設定しています。
4.  `st.button`で「サムネイルを抽出」ボタンを作成します。
5.  ボタンが押されたら、入力されたURLを改行で分割し、それぞれのURLに対して`get_qiita_thumbnail`関数を呼び出します。
6.  取得したサムネイルURLを`st.image`で表示します。サムネイルが見つからなかった場合やエラーが発生した場合は、その旨をユーザーに伝えます。

---

# まとめ
今回は、StreamlitとPythonを用いてQiita記事のサムネイル画像を抽出するWebアプリを開発しました。

* **Streamlit**を使うことで、Pythonの知識だけで手軽にWebアプリを構築できることを実感しました。
* `requests`と`Beautiful Soup`を組み合わせることで、Webスクレイピングが簡単に行えることも改めて認識できました。

このアプリは、Qiitaの記事をまとめてチェックしたい時や、特定の記事のサムネイルデザインを参考にしたい時などに活用できるかと思います。

この記事が、皆さんのWebアプリ開発やPythonでのWebスクレイピングの学習のきっかけになれば幸いです。

最後までお読みいただきありがとうございました！