PythonのRequestsとSQLAlchemyを使用し指定したURLのタイトルを取得しデータベースに書き込んでみます。
今回はRequests、BeautifulSoup、SQLAlchemyを用います。これらのライブラリ・モジュールが事前にインストールされているかを確認し実行する場合は実行してください。
■Python

今回のPythonのバージョンは、「3.8.5」を使用しています。(Windows11)
■RequestsとSQLAlchemyを使用し指定したURLのタイトルを取得しデータベースに書き込む
では、早速RequestsとSQLAlchemyを使用し指定したURLのタイトルを取得しデータベースに書き込むスクリプトを書いていきます。
■コード
import requests
from bs4 import BeautifulSoup
from sqlalchemy import create_engine, Column, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# URLからタイトルを抽出する関数
def extract_title(html):
soup = BeautifulSoup(html, 'html.parser')
title = soup.title.string
return title
# データベースモデル
Base = declarative_base()
class Title(Base):
__tablename__ = 'titles'
url = Column(String, primary_key=True)
title = Column(String)
# データベースの設定
engine = create_engine('')
Session = sessionmaker(bind=engine)
session = Session()
# データベースの初期化
Base.metadata.create_all(engine)
# URLからタイトルを取得してデータベースに保存する関数
def save_title(url):
response = requests.get(url)
title = extract_title(response.text)
existing_title = session.query(Title).filter_by(url=url).first()
if existing_title:
existing_title.title = title
else:
new_title = Title(url=url, title=title)
session.add(new_title)
session.commit()
# 使用例
save_title('https://www.yahoo.co.jp/')まず、extract_title(html)関数では、引数としてHTMLのテキストを受け取ります。BeautifulSoupを使用してHTMLをパースし、title要素の文字列を取得します。取得したタイトルを返します。
そして、Titleモデルでは、SQLAlchemyのBaseクラスを継承しています。’titles’という名前のテーブルを定義します。
urlとtitleの2つのカラムを持ち、urlカラムを主キーに設定します。
次にデータベースの設定を行います。create_engine関数を使用して、データベースに接続するためのエンジンを作成します。今回はオンラインDBサービスである「ElephantSQL(https://www.elephantsql.com/)」を用います。ElephantSQLは予め「test_db」という名前でインスタンスを作り、インスタンスのDetailsから「URL」の情報をコピーします。

コピーするとURLは「postgres://dsppyfom:***@heffalump.db.elephantsql.com/dsppyfom」のようなものとなっていますが、「postgresql://dsppyfom:***@heffalump.db.elephantsql.com/dsppyfom」と先頭の部分を変更します。変更しないと「sqlalchemy.exc.NoSuchModuleError: Can’t load plugin: sqlalchemy.dialects:postgressql」というエラーが出力されます。
接続先のデータベースの情報を引数に指定します。sessionmakerを使用してセッションを作成し、エンジンにバインドします。sessionオブジェクトを作成します。
設定語、データベースの初期化します。Base.metadata.create_all(engine)を呼び出すことで、データベース内にモデルに対応するテーブルを作成します。
テーブルを作成後、save_title(url)関数を定義します。引数としてURLを受け取ります。requests.get(url)を使用して指定したURLからHTMLを取得します。取得したHTMLをextract_title関数に渡してタイトルを抽出します。session.query(Title).filter_by(url=url).first()を使用して、データベース内に同じURLのデータが既に存在するか確認します。存在する場合は、既存のタイトルを更新します。存在しない場合は、新しいデータとしてタイトルを追加します。変更をデータベースにコミットします。
最後に、save_title(‘https://www.yahoo.co.jp/’)で関数を呼び出します。使用例として「’https://www.yahoo.co.jp/’」のURLからタイトルを取得し、データベースに保存します。
■検証・実行
今回書いたスクリプトを「web_url.py」という名前でPythonが実行されている作業ディレクトリ(カレントディレクトリ)に保存し、コマンドプロンプトから実行してみます。
![]()
web_url.py:14: MovedIn20Warning: The ``declarative_base()`` function is now available as sqlalchemy.orm.declarative_base(). (deprecated since: 2.0) (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9) Base = declarative_base()
実行してみると「MovedIn20Warning」という警告は表示されましたがデータベースへの書き込みは完了しました。
完了後、ElephantSQL上からテーブルを確認すると、テーブル内にデータが書き込まれていることが確認できました。
web_url.py:14: MovedIn20Warning: The ``declarative_base()`` function is now available as sqlalchemy.orm.declarative_base(). (deprecated since: 2.0) (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9) Base = declarative_base()
なお、上記の警告ですが、下記のように変更すると問題を解決できます。
■修正前
import requests from bs4 import BeautifulSoup from sqlalchemy import create_engine, Column, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base
■修正後
import requests from bs4 import BeautifulSoup from sqlalchemy import create_engine, Column, String from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import declarative_base


コメント