python-wordpress-xmlrpc
でWordPressから記事一覧を取得しようとして躓いた時の話。
環境
環境情報
OS: Windows 11
Python環境: Anacondaで仮想環境を構築
Pythonバージョン: 3.10.4
module:
- python-wordpress-xmlrpc バージョン: 2.3
エラーメッセージ
以下のドキュメントを参考に記事一覧の取得を試みるが、collections
の処理中にエラーが出る。
GetListPosts.py
# 必要なモジュールを持ってくる
from wordpress_xmlrpc import Client, methods
from wordpress_xmlrpc.methods.posts import GetPosts
# client情報
url = 'https://hogehoge.com/xmlrpc.php' # トップページのアドレス末尾に/xmlrpc.phpを付ける
user = 'hoge' # WordPressのユーザ名
password = 'hogehoge' # WordPressのパスワード
client = Client(url, user, password)
# 記事一覧の取得。出力はリスト型。
posts = client.call(GetPosts())
エラーメッセージ
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [6], in <cell line: 1>()
----> 1 posts = client.call(GetPosts())
File ~\anaconda3\envs\py310\lib\site-packages\wordpress_xmlrpc\base.py:46, in Client.call(self, method)
44 else:
45 raise
---> 46 return method.process_result(raw_result)
File ~\anaconda3\envs\py310\lib\site-packages\wordpress_xmlrpc\base.py:128, in XmlrpcMethod.process_result(self, raw_result)
126 if isinstance(raw_result, dict_type):
127 return self.results_class(raw_result)
--> 128 elif isinstance(raw_result, collections.Iterable):
129 return [self.results_class(result) for result in raw_result]
131 return raw_result
AttributeError: module 'collections' has no attribute 'Iterable'
原因と対策
エラー原因
pythonのバージョン違いで、モジュールの collections
が collections.abc
に置き換わっているのが原因。
python3.8以上からこの問題が起こる模様。
エラー対策
2022/9現在、python-wordpress-xmlrpc
はバージョン2.3から暫く更新されておらず、当該バグも修正されていない。
ここでは、python-wordpress-xmlrpc
内でエラーが起こっているXmlrpcMethod.process_result
の関数を、修正した自作の関数に置き換えて処理を進める。
修正後のコード
GetListPosts_ver2.py
# 修正するモジュールをインポート
from wordpress_xmlrpc.base import XmlrpcMethod
# 修正するにあたり、必要な関連モジュールをインポート
from wordpress_xmlrpc.compat import xmlrpc_client, dict_type
import collections.abc
# 元の関数をコピペして、自作関数を作成
def my_process_result(self, raw_result):
if self.results_class and raw_result:
if isinstance(raw_result, dict_type): # dict_type は wordpress_xmlrpc.compat からインポートしている
return self.results_class(raw_result)
elif isinstance(raw_result, collections.abc.Iterable): # collections => collections.abc に書き換え
return [self.results_class(result) for result in raw_result]
return raw_result
# 自作関数に置き換える。
XmlrpcMethod.process_result = my_process_result
###############################
### 以下、記事一覧取得のコード ###
###############################
from wordpress_xmlrpc import Client, methods
from wordpress_xmlrpc.methods.posts import GetPosts
# client情報
url = 'https://hogehoge.com/xmlrpc.php' # トップページのアドレス末尾に/xmlrpc.phpを付ける
user = 'hoge' # WordPressのユーザ名
password = 'hogehoge' # WordPressのパスワード
client = Client(url, user, password)
# 記事一覧の取得。出力はリスト型。
posts = client.call(GetPosts())
参考
- Qiita記事
- GitHub
- collections.abc について
奮闘ログ
詳細はブログに記載。