AIと実践!お試し記録集🤖

AIと協力してサヴァイヴしていく過程の記録。

【Python】特定のウェブページからテキストを取得

 

前回やったこと

前回は、特定のウェブページから画像を取得しました。

mossan99-b.hateblo.jp

最終目的は複数のややこしいファイル名の変更を同時に行う、ということなんですが、下準備的な作業で、特定のウェブページからテキストを取得してみます。いつものように、VSCODEGithub CopilotでAIパイセンにお伺いを立てながら😁コード書きます。

AIパイセンに聞いてみよう

以下のプロンプトでハイセンに聞きます。

特定のウェブページからテキストを取得したい

以下のコードが返ってきました。

#特定のウェブページからテキストを取得 by mossan99

import requests
from bs4 import BeautifulSoup

def get_web_text(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, 'html.parser')
        return soup.get_text()
    else:
        return None

if __name__ == "__main__":
    url = "https://example.com"
    text = get_web_text(url)
    if text:
        print(text)
    else:
        print("Failed to retrieve the web page.")

以下のプロンプトを加えます

ウィンドウを出してテキストの保存場所を指定したい

さらに

Webページの名前をテキストファイルの名前にしたい

これから返ってきたコードを実行したところ、以下のエラーが出ました。。

  line 34, in 
safe_title = re.sub(r'[\\/*?:"<>|]', "", title)
                 ^^
NameError: name 're' is not defined. Did you forget to import 're'?

プロンプトにコピペして改善をお願いします。

モジュールをインポートするのを忘れていたため、エラーが発生しています。reモジュールをインポートし、コードを修正します。

忘れてたんかい!ということで、修正のコードが返ってきました

# 特定のウェブページからテキストを取得 by mossan99

import requests
from bs4 import BeautifulSoup
from tkinter import Tk, filedialog, messagebox
import re  # reモジュールをインポート

def get_web_text_and_title(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, 'html.parser')
        title = soup.title.string if soup.title else "untitled"
        text = soup.get_text()
        return text, title
    else:
        return None, None

def save_text_to_file(text, file_path):
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(text)

def select_save_location(default_filename):
    root = Tk()
    root.withdraw()
    messagebox.showinfo("保存場所選択", "テキストを保存する場所を選択してください。")
    file_path = filedialog.asksaveasfilename(initialfile=default_filename, defaultextension=".txt", filetypes=[("Text files", "*.txt")])
    root.destroy()
    return file_path

if __name__ == "__main__":
    url = "https://mossan99-b.hateblo.jp/entry/2025/02/05/171251"
    text, title = get_web_text_and_title(url)
    if text:
        # ファイル名に使用できない文字を置き換え
        safe_title = re.sub(r'[\\/*?:"<>|]', "", title)
        save_path = select_save_location(f"{safe_title}.txt")
        if save_path:
            save_text_to_file(text, save_path)
            print(f"テキストが正常に保存されました: {save_path}")
        else:
            print("保存場所が選択されませんでした。")
    else:
        print("ウェブページの取得に失敗しました。")

実行して、保存されたテキストが以下です。

えっっw。タイトルの文字しか入ってない。。。聞き方がおかしかったんですかね。次のように聞き直します。

ブログのタイトルは消去して、画像データのキャプションのテキストを取得してほしい。

コードのコメントもついでに追加してもらって、返ってきたのが以下です。

# 特定のウェブページからテキストを取得 by mossan99

import requests
from bs4 import BeautifulSoup
from tkinter import Tk, filedialog, messagebox
import re  # reモジュールをインポート

# 指定されたURLから画像データのキャプションを取得する関数
def get_image_captions(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, 'html.parser')
        # 画像のalt属性をキャプションとして取得
        captions = [img['alt'] for img in soup.find_all('img') if 'alt' in img.attrs]
        return captions
    else:
        return None

# 取得したテキストデータを指定されたファイルパスに保存する関数
def save_text_to_file(text, file_path):
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(text)

# ファイル保存ダイアログを表示して保存場所を選択する関数
def select_save_location(default_filename):
    root = Tk()
    root.withdraw()
    messagebox.showinfo("保存場所選択", "テキストを保存する場所を選択してください。")
    file_path = filedialog.asksaveasfilename(initialfile=default_filename, defaultextension=".txt", filetypes=[("Text files", "*.txt")])
    root.destroy()
    return file_path

if __name__ == "__main__":
    url = "https://mossan99-b.hateblo.jp/entry/2025/02/05/171251"
    captions = get_image_captions(url)
    if captions:
        # キャプションを改行で結合してテキストにする
        text = "\n".join(captions)
        # ファイル名に使用できない文字を置き換え
        safe_title = re.sub(r'[\\/*?:"<>|]', "", "image_captions")
        save_path = select_save_location(f"{safe_title}.txt")
        if save_path:
            save_text_to_file(text, save_path)
            print(f"テキストが正常に保存されました: {save_path}")
        else:
            print("保存場所が選択されませんでした。")
    else:
        print("ウェブページの取得に失敗しました。")

実行して出来上がったテキストファイルが以下。

うーんうまくいかない。。。。聞き方をどうしよう。ウェブページを右クリックして「検証」を押して、コードの中身を見てみます。

 

 

「figure class」の「title」のテキストが取得できればOK、となりそうですね。以下のように、聞き直します。

figure classのtitleのテキストのみを取得できるようにコードを改善して欲しい

以下が返ってきました

# 特定のウェブページからテキストを取得 by mossan99

import requests
from bs4 import BeautifulSoup
from tkinter import Tk, filedialog, messagebox
import re  # reモジュールをインポート

# 指定されたURLからfigureクラスのtitle属性を持つ要素のテキストを取得する関数
def get_figure_titles(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, 'html.parser')
        # figureクラスのtitle属性を持つ要素のテキストを取得
        titles = [figure['title'] for figure in soup.find_all('figure') if 'title' in figure.attrs]
        return titles
    else:
        return None

# 取得したテキストデータを指定されたファイルパスに保存する関数
def save_text_to_file(text, file_path):
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(text)

# ファイル保存ダイアログを表示して保存場所を選択する関数
def select_save_location(default_filename):
    root = Tk()
    root.withdraw()
    messagebox.showinfo("保存場所選択", "テキストを保存する場所を選択してください。")
    file_path = filedialog.asksaveasfilename(initialfile=default_filename, defaultextension=".txt", filetypes=[("Text files", "*.txt")])
    root.destroy()
    return file_path

if __name__ == "__main__":
    url = "URL" # ここに対象のURLを入力してください
    titles = get_figure_titles(url)
    if titles:
        # タイトルを改行で結合してテキストにする
        text = "\n".join(titles)
        # ファイル名に使用できない文字を置き換え
        safe_title = re.sub(r'[\\/*?:"<>|]', "", "figure_titles")
        save_path = select_save_location(f"{safe_title}.txt")
        if save_path:
            save_text_to_file(text, save_path)
            print(f"テキストが正常に保存されました: {save_path}")
        else:
            print("保存場所が選択されませんでした。")
    else:
        print("ウェブページの取得に失敗しました。")

実行した結果が以下です

 

お!うまくいきました。テキストを取得した順番も問題なさそうですが、前回画像を取得したときに順番がバラバラになることもあったので、修正を追加したいと思います。あと、テキストの先頭に、カウントもつけるようにパイセンに頼んでみます。

Webページの上から順番にテキストを取得して、さらに、各テキストの頭に「0000_」がフォーマットのカウンタを追加

実行した結果が以下

よし!無事にうまくいきました。これで準備は良さそうですね。次回は、これらを組み合わせファイル名の変更をやってみようかなと。

 

 

最終コードは、以下に書いておきます。

 

この続きはcodocで購入