PythonでOGPを取得する方法を検証しました。
結論から言うと、Seleniumによるスクレイピングが最強でした。
本記事の内容
- OGPを取得する方法一覧
- ogp
- PyOpenGraph
- py-ogp-parser
- Seleniumによるスクレイピング
それでは、上記に沿って解説していきます。
OGPを取得する方法一覧
OGPを取得する方法を4つ検証しました。
- ogp
- PyOpenGraph
- py-ogp-parser
- Seleniumによるスクレイピング
上の3つは、Pythonのライブラリです。
最後の1つは、自分でスクレイピングするという方法です。
「自分で」と言っても、Seleniumなどのライブラリは利用します。
検証する環境について、説明しておきます。
Pythonのバージョンは、現時点(2021年4月末)における最新のPythonです。
>python -V Python 3.9.4
OSは、Windows 10を利用します。
しかし、LinuxでもmacOSでもそれほど違いはないでしょう。
では、一つづつOGPを取得する方法を検証していきましょう。
最初は、ogpというそのまんまの名前であるライブラリです。
ogp
結論から言うと、使えません。
ogp PyPlページ
https://pypi.org/project/ogp/
検索で真っ先にヒットしたライブラリです。
最新版は、0.9.1となります。
この0.9.1は、2012年8月2日に公開されています。
全くメンテナンスされていません。
あまり期待せずに、インストールしてみます。
pip install ogp
上記を実行すると、途中でエラーとなります。
ERROR: Cannot install ogp==0.8, ogp==0.9 and ogp==0.9.1 because these package versions have conflicting dependencies. The conflict is caused by: ogp 0.9.1 depends on BeautifulSoup ogp 0.9 depends on BeautifulSoup ogp 0.8 depends on BeautifulSoup To fix this you could try to: 1. loosen the range of package versions you've specified 2. remove package versions to allow pip attempt to solve the dependency conflict ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies
依存するBeautifulSoupのバージョンで問題が発生しているようです。
詳細は、追いかけません。
そもそも、古すぎてアウトということで十分です。
では、次はPyOpenGraphを検証します。
PyOpenGraph
結論から言うと、使えません。
PyOpenGraph PyPlページ
https://pypi.org/project/PyOpenGraph/
PyOpenGraphは、OGP公式サイトで紹介されています。
OGP公式
https://ogp.me/
公式がおススメするライブラリと言えます。
このライブラリの最新版は、0.2です。
0.2は、2010年5月9日に公開されています。
期待せずにインストールしてみます。
pip install PyOpenGraph
上記を実行すると、インストールが始まります。
無事に終了。
確認してみます。
>pip list Package Version ----------- ------- pip 21.1 PyOpenGraph 0.2 setuptools 56.0.0
パッケージもちゃんとインストールされています。
では、動作確認を行います。
import PyOpenGraph
このimport文だけのコードを実行すると、以下のエラーが出ます。
ModuleNotFoundError: No module named 'PyOpenGraph'
これも古すぎて、エラーを追いかける気にもなりません。
そもそも、Python3には未対応の可能性すらありえます。
では、次はpy-ogp-parserの検証していきます。
py-ogp-parser
結論から言うと、使いません。
基本的には使えますが、OGPを取得できない場合があります。
スクレイピング対策をしているサイトでは、無力な場合があります。
py-ogp-parser PyPlページ
https://pypi.org/project/py-ogp-parser/
py-ogp-parserの最新版は、0.2.1となります。
この0.2.1は、2018年12月24日に公開されています。
これは、今までのライブラリと比べると新しい方です。
期待ができます。
インストールは、次のコマンドで行います。
pip install py-ogp-parser
インストール状況を確認します。
>pip list Package Version -------------- --------- beautifulsoup4 4.9.3 certifi 2020.12.5 chardet 4.0.0 idna 2.10 pip 21.1 py-ogp-parser 0.2.1 requests 2.25.1 setuptools 56.0.0 soupsieve 2.2.1 urllib3 1.26.4
多くのパッケージがインストールされました。
基本的なモノが多いとは言え、これは嫌な感じです。
なぜなら、依存パッケージが多いと気軽に導入ができません。
既存環境には、なるべく影響を与えたくありません。
とりあえずは、動作確認をしてみます。
from py_ogp_parser.parser import request status_code, result = request('https://www.watch.impress.co.jp/docs/news/1316107.html') print(status_code) print(result)
上記を実行した結果は、以下。
200 {'title': 'iOS 14.5公開。マスクでもApple WatchでiPhoneロック解除 - Impress Watch', 'ogp': {'date': ['2021-04-27T11:42:36+09:00'], 'fb:app_id': ['313703452412789'], 'og:type': ['article'], 'og:locale': ['ja_JP'], 'og:site_name': ['Impress Watch'], 'og:url': ['https://www.watch.impress.co.jp/docs/news/1316107.html'], 'og:title': ['iOS 14.5公開。マスクでもApple WatchでiPhoneロック解除'], 'og:description': ['アップルは27日、iOS 14.5を提供開始した。Apple Watchと連携し、マスクを着用していてもiPhoneのFace IDロックをApple Watchで解除できる機能が提供される。また、紛失防止タグの「AirTag」に対応する。'], 'og:image': ['https://www.watch.impress.co.jp/img/ipw/list/1316/107/ios1.jpg'], 'article:published_time': ['2021-04-27T02:57:32+09:00'], 'article:modified_time': ['2021-04-27T11:42:36+09:00'], 'article:tag': ['Apple,テック']}, 'seo': {'author': ['株式会社インプレス'], 'copyright': ['Copyright © Impress Corporation. All Rights Reserved.'], 'keywords': ['Apple,テック'], 'creation_date': ['2021-04-27T02:57:32+09:00'], 'ipw:id': ['1316107'], 'ipw:site': ['ipw'], 'ipw:year': ['2021'], 'ipw:month': ['4'], 'ipw:day': ['27'], 'ipw:firstpage': ['/docs/news/1316107.html'], 'twitter:card': ['summary_large_image'], 'twitter:site': ['@impress_watch'], 'twitter:image:src': ['https://www.watch.impress.co.jp/img/ipw/list/1316/107/ios1.jpg'], 'twitter:url': ['https://www.watch.impress.co.jp/docs/news/1316107.html'], 'twitter:title': ['iOS 14.5公開。マスクでもApple WatchでiPhoneロック解除'], 'twitter:description': ['アップルは27日、iOS 14.5を提供開始した。Apple Watchと連携し、マスクを着用していてもiPhoneのFace IDロックをApple Watchで解除できる機能が提供される。また、紛失防止タグの「AirTag」に対応する。'], 'distributable': ['licensee'], 'referrer': ['always'], 'robots': ['max-image-preview:large']}}
OGPが取得できています。
ただし、これはスクレイピング対策をしていないページだからです。
上手く行かないのは、メルカリの商品ページです。
メルカリはがっつりとスクレイピング対策をしています。
status_code, result = request('https://www.mercari.com/jp/items/m82674740968/')
上記のようにURLを変更して、プログラムを実行した結果は以下。
403 {'title': '403 Forbidden', 'ogp': {}, 'seo': {}}
403エラーで弾かれています。
以上、py-ogp-parserの検証でした。
次は、Seleniumによるスクレイピングの検証です。
Seleniumによるスクレイピング
結論から言うと、使えます。
メルカリのページからもOGPが取得できます。
そのためには、Seleniumでスクレピングができる環境が必要です。
その環境を作るためには、以下が必要となります。
- Selenium
- BeautifulSoup4
- lxml
これらのインストール方法は、次の記事で解説しています。
記事内の「スクレイピングするための準備」が参考になります。
準備が整ったら、次のサンプルコードを動かしてみましょう。
import bs4 import traceback import re from selenium import webdriver from selenium.webdriver.chrome.options import Options CHROMEDRIVER = "chromedriver.exeのパス" TARGET_URL = "https://www.mercari.com/jp/items/m43435569677/" # ドライバー準備 def get_driver(): # ヘッドレスモードでブラウザを起動 options = Options() options.add_argument('--headless') # ブラウザーを起動 driver = webdriver.Chrome(CHROMEDRIVER, options=options) return driver # 対象ページのソース取得 def get_source_from_page(driver, page): try: # ターゲット driver.get(page) page_source = driver.page_source return page_source except Exception as e: print("Exception\n" + traceback.format_exc()) return None # ソースからスクレイピングする def get_data_from_source(src): # スクレイピングする soup = bs4.BeautifulSoup(src, features='lxml') try: items = {} elems = soup.find_all("meta", property=re.compile(r'^og')) for elem in elems: key = elem['property'][3:] if key == "image:url": key = "image" items[key] = elem['content'] return items except Exception as e: print("Exception\n" + traceback.format_exc()) return None if __name__ == "__main__": # ブラウザのdriver取得 driver = get_driver() page = TARGET_URL source = get_source_from_page(driver, page) # 記事ページURL取得 ogp = get_data_from_source(source) print(ogp) # 閉じる driver.quit()
上記のプログラムを実行した結果は、以下。
{'type': 'website', 'site_name': 'メルカリ スマホでかんたん フリマアプリ', 'title': '4.21 w-1097 GRL\u3000グレイル\u3000マキシ\u3000ロングスカート(¥1,500) - メルカリ スマホでかんたん フリマアプリ', 'description': '数ある中からご覧頂き、ありがとうございます。プロフィールを必ずお読みになってからのご購入をお願いいたします。サイズ:Mウエスト幅 約58cmヒップ 約82 cm総丈 約88cm色\u3000グリーン系素材表記が分かる場合は、画像にて載せてますのでご確認下さい。素人の採寸ですので若干の誤差はご了承ください。usedということをご理解して頂いた上でのご購入をお願い致します。ご質問などが御座いましたらお気軽にコメント下さい。', 'url': 'https://www.mercari.com/jp/items/m43435569677/', 'image': 'https://static.mercdn.net/item/detail/orig/photos/m43435569677_1.jpg?1618973940'}
py-ogp-parserでは、メルカリのページへアクセスすらできませんでした。
しかし、SeleniumによるスクレイピングであればOGPを取得できます。
なお、定数は以下の箇所で設定しています。
CHROMEDRIVER = "chromedriver.exeのパス" TARGET_URL = "https://www.mercari.com/jp/items/m43435569677/"
CHROMEDRIVERに関しては、次の記事で説明しています。
TARGET_URLには、OGPを取得したページのURLを設定します。
なお、プログラムの詳細に関しては、本サイトにおける他の記事で説明しています。
基本的には、同じような関数を利用しています。
- get_driver
- get_source_from_page
- get_data_from_source
よって、上記の関数で本サイトを検索するとよいでしょう。
以上、Seleniumによるスクレイピングの検証でした。
より完璧を求めるなら、Seleniumによるスクレイピングがおススメです。