Python embeddedのエラー対処法

Python embeddedでmatplotlibを使おうとするとimport errorが起きるエラーです.

import matplotlib

これでエラーが起こる.

ImportError: DLL load failed: The specified module could not be found.

原因

matplotlibを動作するにはMicrosoft Visual C++ のダウンロード が必要です.下記からダウンロードする必要があります.

https://support.microsoft.com/ja-jp/topic/%E6%9C%80%E6%96%B0%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%82%8B-visual-c-%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89-2647da03-1eea-4433-9aff-95f26a218cc0

参考文献

https://www.python.org/downloads/windows/

pandasの表示列数が少ないので増やす

1

terminalで作業しているとpandasの表示列数が少ない時がある。main.py

(Pdb) pd.DataFrame(data['positions'])
  instrument                                               long  ... unrealizedPL marginUsed
0    USD_CNH  {'units': '0', 'pl': '0.0000', 'resettablePL':...  ...     -39.1847  2085.3600
1    USD_CHF  {'units': '0', 'pl': '0.0000', 'resettablePL':...  ...     131.7863  2085.3600
2    NZD_USD  {'units': '400', 'averagePrice': '0.70474', 'p...  ...     175.8605  1184.0320
3    USD_CAD  {'units': '0', 'pl': '0.0000', 'resettablePL':...  ...     118.2543  1668.2880
4    GBP_USD  {'units': '400', 'averagePrice': '1.33051', 'p...  ...     -62.2680  2772.4000
5    AUD_USD  {'units': '400', 'averagePrice': '0.74940', 'p...  ...     169.8251  1257.0400
6    USD_JPY  {'units': '200', 'averagePrice': '104.144', 'p...  ...      21.0000   834.1440
7    EUR_USD  {'units': '1000', 'averagePrice': '1.21002', '...  ...     382.7307  5063.5600

もっと列数をみたい場合、main.py

(Pdb) import pandas as pd
(Pdb) pd.set_option('display.max_rows', 500)
(Pdb) pd.set_option('display.max_columns', 500)
(Pdb) pd.set_option('display.width', 1000)

と打つと、main.py

(Pdb) pd.DataFrame(data['positions'])
  instrument                                               long                                              short        pl resettablePL financing commission dividendAdjustment guaranteedExecutionFees unrealizedPL marginUsed
0    USD_CNH  {'units': '0', 'pl': '0.0000', 'resettablePL':...  {'units': '-400', 'averagePrice': '6.53311', '...    0.0000       0.0000   -1.1446     0.0000             0.0000                  0.0000     -39.1847  2085.3600
1    USD_CHF  {'units': '0', 'pl': '0.0000', 'resettablePL':...  {'units': '-400', 'averagePrice': '0.88884', '...    0.0000       0.0000   -2.2664     0.0000             0.0000                  0.0000     131.7863  2085.3600
2    NZD_USD  {'units': '400', 'averagePrice': '0.70474', 'p...  {'units': '0', 'pl': '0.0000', 'resettablePL':...    0.0000       0.0000   -0.9832     0.0000             0.0000                  0.0000     175.8605  1184.0320
3    USD_CAD  {'units': '0', 'pl': '0.0000', 'resettablePL':...  {'units': '-400', 'averagePrice': '1.27810', '...    0.0000       0.0000   -4.0178     0.0000             0.0000                  0.0000     118.2543  1668.2880
4    GBP_USD  {'units': '400', 'averagePrice': '1.33051', 'p...  {'units': '0', 'pl': '0.0000', 'resettablePL':...    0.0000       0.0000   -1.7342     0.0000             0.0000                  0.0000     -62.2680  2772.4000
5    AUD_USD  {'units': '400', 'averagePrice': '0.74940', 'p...  {'units': '0', 'pl': '0.0000', 'resettablePL':...    0.0000       0.0000   -1.1558     0.0000             0.0000                  0.0000     169.8251  1257.0400
6    USD_JPY  {'units': '200', 'averagePrice': '104.144', 'p...  {'units': '0', 'pl': '0.0000', 'resettablePL':...  130.6000     130.6000   -3.1302     0.0000             0.0000                  0.0000      21.0000   834.1440
7    EUR_USD  {'units': '1000', 'averagePrice': '1.21002', '...  {'units': '0', 'pl': '20.1626', 'resettablePL'...   20.1626      20.1626  -16.6970     0.0000             0.0000                  0.0000     382.7307  5063.5600

と表示されるようになります。

参考文献

How do I expand the output display to see more columns of a pandas Dat…https://stackoverflow.com

【保存版】Flaskで画像を操作する際の6パターンを書き分ける

1

Flask上で画像を操作する際のソースコードのパターンについてですが、 画像の生成元をどうするかというもので3パターン、画像の最終的な処理方法をどうするかというもので2パターンで(組み合わせで)合計6パターンがあると思います。Flaskで画像処理を実装しようとするとこれらを書き分ける必要がありますのでそれについて記載します。

画像の生成元の3つとは

  • HTMLからFlaskで立てたURLへ直接画像がアップロードされる場合、
  • Flaskの関数の中でmatplotlibなどで生成する場合、
  • クラウドないしはローカルフォルダなどに保存されている画像を読み込んでくる場合

の3つです。

最終的な処理方法として2つあるというのは、

  • 画像をクラウドないしはローカルフォルダなどに保存する場合と
  • クライアント側へ画像をreturnする場合

の2つです。メタ情報だけ抽出して文字列で返す場合などもあると思いますが、これはJSONなどでリターンすればOKなので上記6パターンで対応できると思います。

Flaskで画像を操作したいと思うと、この6パターンについてソースコードを書き分ける必要があり、かなり大変です
しかし、幸いなことに、画像をどこかに保存する場合とクライアント側へ返す場合については画像をメモリ上でBlob形式であらかじめ保存することができれば同時に対応できますので、事実上かき分けなければならないのは3パターンとなります。
この記事では、画像をメモリ上でBlob形式で書き出すコードを使いながらこの3パターンについて整理したいと思います。

なお、ここでは処理後の画像の保存先としてGoogle Cloud Storageを利用した例で説明しますが、適宜AWSのS3、ローカルのフォルダの場所などと読み替えて下さい。今回記載するサンプルコードは下記の3つです。

1. 画像をFlaskの関数内で生成し、メモリ上でBlob形式で保存したのちにGCSへ保存しクライアント側へ返す
2. 画像をクライアントから受け取り、メモリ上でBlob形式で保存したのちにGCSへ保存しクライアント側へ返す
3. 画像をGSCから読み取り、メモリ上でBlob形式で保存したのちにGCSへ保存しクライアント側へ返す

画像をFlaskの関数内で生成し、メモリ上でBlob形式で保持したのちにGCSへ保存とクライアント側へ返す

# coding: utf-8
import os
import io
import time
import string
import random
import datetime
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from PIL import Image
import cv2
from flask import Flask, render_template, request, redirect, url_for, send_from_directory,send_file
from flask_cors import CORS
from google.cloud import storage
from google.cloud.storage import Blob
import inspect
import numpy as np
import cv2

app = Flask(__name__)
CORS(app)

@app.route('/',methods=["GET","POST"])
def hello():
    buf = io.BytesIO()
    x = np.linspace(0, 10)
    y = np.sin(x)
    plt.plot(x, y)
    plt.savefig(image, format='png')
    buf.seek(0)

    destination_blob_name = "path/to/your/file_on_gcs.jpg"
    blob = Blob(destination_blob_name, bucket)
    blob.upload_from_string(data=buf.getvalue(), content_type=content_type)

    return send_file(
        buf,attachment_filename=source_blob_name,as_attachment=True
    )
if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

ポイントは2つあって、一つ目はGUIに対応していないFlask上でmatplotlibが動作するようにmatplotlib.use(‘Agg’)というコードを入れていること二つ目はsavefigの部分でメモリ上でファイルを書き出していることです。ローカルで動かす場合は、普通にHDD(SSD?)にjpgなどで書き出しても問題ないと思いますが、クラウドなどだとローカルへのアクセスが禁止されていることが往々にしてあります。この場合に備えて、メモリ上でファイルの読み書きを行うioモジュールを使ってメモリ上に画像を出力しています。ここは個人的に結構ポイントです。

それでは次に既に保存されている画像を取ってくる場合です。

画像をGSCから読み取り、メモリ上でBlob形式で保持したのちにGCSへ保存とクライアント側へ返す

クラウドからデータを持ってきます。重いデータなどは予め画像にしておくと便利ですのでよく使っています。

# coding: utf-8
import os
import io
import time
import string
import random
import datetime
import numpy as np
from PIL import Image
import cv2
from flask import Flask, render_template, request, redirect, url_for, send_from_directory,send_file
from flask_cors import CORS
from google.cloud import storage
from google.cloud.storage import Blob
import inspect
import numpy as np
import cv2

app = Flask(__name__)
CORS(app)

@app.route("/", methods=["GET", "POST"])
def hello():
    os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = './for-dev-268800-ed3aecf9b014.json'
    storage_client = storage.Client()
    bucket = storage_client.get_bucket('for-dev-268800.appspot.com')#"'for-dev-268800.appspot.com'

    source_blob_name = "path/to/your/file_on_gcs.jpg"
    
    #検索する場合はここを使う
    """
    blobs = bucket.list_blobs(prefix="")
    for blob in blobs:
        print(blob.name)
        print(dir(blob))
        print(blob.content_type)
        source_blob_name = blob.name
        content_type = blob.content_type
    print(inspect.getfullargspec(bucket.list_blobs))
    """    

    blob = bucket.get_blob(source_blob_name)
    buf = io.BytesIO()
    blob.download_to_file(buf)
    buf.seek(0)

    destination_blob_name = "path/to/your/file_on_gcs.jpg"
    blob = Blob(destination_blob_name, bucket)
    blob.upload_from_string(data=buf.getvalue(), content_type=content_type)

    return send_file(
        buf,attachment_filename=source_blob_name,as_attachment=True
    )

if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

上記ファイルを実行しFlaskサーバが立てたあと、こちらについてはブラウザなどで直接叩いたいただければ問題ありません。

画像をクライアントから受け取り、メモリ上でBlob形式で保持したのちにGCSへ保存とクライアント側へ返す

最後のパターンです。これはクライアントから画像を受け取る場合ですが、要するにユーザがブラウザから画像を選択してアップロードするよく使うやつです(curlでこれをコード化すると、画像の一括アップロードなどにも使えます)。

# coding: utf-8
import os
import io
import time
import string
import random
import datetime
import numpy as np
from PIL import Image
import cv2
from flask import Flask, render_template, request, redirect, url_for, send_from_directory,send_file
from flask_cors import CORS
from google.cloud import storage
from google.cloud.storage import Blob
import inspect
import numpy as np
import cv2

app = Flask(__name__)
CORS(app)

@app.route("/", methods=["GET", "POST"])
def hello():   
    if request.files['image']:
        filename = request.files['image'].filename
        content_type = request.files['image'].content_type
        # 画像として読み込み
        stream = request.files['image'].stream
        img_array = np.asarray(bytearray(stream.read()), dtype=np.uint8)
        img = cv2.imdecode(img_array, 1)
        is_success, buffer = cv2.imencode(".jpg", img)
        buf = io.BytesIO(buffer)
        #buf = io.BytesIO()
        buf.seek(0)

        os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = './path/to/your/credential_goole.json'
        storage_client = storage.Client()
        bucket = storage_client.get_bucket('your_backetname.com')
        blob = Blob(filename, bucket)
        blob.upload_from_string(data=buf.getvalue(), content_type=content_type)

        return send_file(
            buf,attachment_filename=filename,as_attachment=True
        )

if __name__ == "__main__":
    app.run(host='127.0.0.1',debug=True)

上記ファイルを実行しFlaskサーバが立てたあと、こちらについては画像をHTMLからアップロードする必要があります。
APIを叩いてcanvas要素に描写するHTMLも載せておきますので、こちらを参考にしてください。buf変数に読み込んだものをOpenCVなどで操作すれば簡単な画像処理ソフトになると思います。

<!doctype html>
<html lang="ja">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

    <title>bootstrapとjquery</title>

  </head>
  <body>

<main>
<article>
  <section>
       <input type="button" value="Start" onclick="main();"/>
        <canvas style="height: 30vw;width:50vh"></canvas>
  </section>
</article>
</main>

<script language="javascript" type="text/javascript">

    function main(){
      var canvas = document.getElementsByTagName('canvas');
      var ctx = canvas[0].getContext('2d');

      var img = new Image();
      img.src = 'http://0.0.0.0:5000';//FlaskでホスティングしたURL

      img.onload = function() {
        img.style.display = 'none'; // ようわからん
        console.log('WxH: ' + img.width + 'x' + img.height)

        ctx.drawImage(img, 0, 0);
        var imageData = ctx.getImageData(0, 0, img.width*2, img.height*2)

        for(x = 0 ; x < 1000 ; x += 10) {
          for(y = 0 ; y < 1000 ; y += 10) {
             ctx.putImageData(imageData, x, y);
          }
        }
      };    }
</script>

  </body>
</html>

curlコマンドでForm送信は代替できます。
HTMLのform送信をcurlコマンドで代替する方法はこちら

Flaskで画像を処理場合のソースコードはパターンごとに書き分ける必要があり、普段は目の前のタスクを終わらせて終わりがちですが、今回は6つのパターンについてまとめました。AWSのS3を使う場合やローカルで完結させる場合も同様に処理できると思いますので、ぜひ参考にしていただけるとうれしいです。

この記事が役に立ったと思ったらLGTMお願いいたします:thumbsup:

Matplotlibで作成したグラフをクライアントへ返す方法についてさらに詳細をまとめたのはこちら

https://qiita.com/NP_Systems/items/9bea70ade73cc48cbdf0

pandasで条件抽出する2つの方法(単一条件、複数条件)

1

pandasで条件抽出する方法には、queryメソッドを使う場合と使わない場合がある。

A列に1-100、B列に101-200、 C列に201から300のデータが並んでいる100行のデータを考える。

df = pd.DataFrame({
    "A":[i for i in range(100)], 
    "B":[i+100 for i in range(100)], 
    "C":[i+200 for i in range(100)],])

メソッドを使用しない場合:

#A列が20未満を抜き出す
df = df[(df["A"]<20)]
#A列が20より大きく、かつ、50未満を抜き出す
df = df[(df["A"]>20)&(df["A"]<50)]
#A列が20より大きく、または、50未満を抜き出す
df = df[(df["Α"]>20)|(dF["B"]<50))

複数条件の場合、かっこで個々の条件を囲む必要がある。

queryメソッドを使用する場合:

単一条件での抽出:

#Aが20未満を抜き出す
df = df.query('A< 20')
df = df.query('(A > 20) and (A < 50)')
df = df.query('(A > 20) | (A < 50)')

個人的にはqueryを使わない方が好みです。

特定の文字列を含む行を取得したい場合はこちら

Pandasでcsvを読み込む

高機能なデータハンドリングが魅力のPythonですが、Pandasを使用すると複雑な処理を1行でできるので便利です。よくわからないけど、とりあえずPythonでデータを操作したいというなら、Pandasでデータを読み込めば間違いありません。

[chat face=”man1″ name=”” align=”left” border=”gray” bg=”none” style=””]汎用的なデータの読み込みならPandasがおススメ![/chat]

そもそもPandasってなんだっけ?

Pandasは、データハンドリング用で使われる最も有名なライブラリのひとつです。
Pythonは本体には最小限の機能しか備えておりません。パソコンにソフトをインストールしてできることを増やすように、Pythonは、追加のパッケージ(ライブラリ)をインストールして様々なことができるようになります。Pandasは、データ処理用のライブラリです。データの読み込みは様々な方法でできますが、最も覚えることが少なく、汎用的な手法として、Pandasでのデータ読み込みがおススメです。
例えばPandasは下記のようなときに使用できます

・Excelデータの読み込み
・CSV形式の読み込み
・txtデータの読み込み

どうやってインストールするの?

Pandasのインストール方法は、大きく分けて二つあります。一つは、Pythonの本体に単独でインストールする方法。もう一つは、Anacondaを利用する方法です。Anacondaとは、よく使用するパッケージをPython本体と一緒にダウンロードできる拡張版Pythonのイメージです。Anacondaは下記からインストールできますが、その場合、すでにPandasは自動でインストールされていますのでそれ以上の環境構築は必要ありません。

pipでインストールする場合:

pip install pandas

Anacondaでインストールする場合(おすすめ):
https://www.anaconda.com/で最新版をインストールすればOK.他の言語でもいえることですが、追加ライブラリのバージョンは、合わせておかないと動きません。これを依存関係といいますが、これらを整えて配布されているのはAnacondaです。Continuum社の有料サービスの無料版というのも安心です。

ホップ:Pandasでのcsvデータを読み込むには?

それでは、実際にPandasでcsvのデータを読み込みます。コードをGitHubにあげておくので、そちらからダウンロードかまいません。web上でPythonを実行できるpaizaのページからコードを貼り付けて実行していただいてもいいと思います。
paizaのページ:https://paiza.io/projects/featured?language=python3

GitHub;https://github.com/awesomerainbows/wp_read_csv

もし初めての場合、どこに何をおいたらいいかわからないと思います。そのときは、読み込みたいcsvとpythonのファイルは同じ階層においてください。おススメは、デスクトップにtestというフォルダを作成して、そこにpythonファイルとcsvの2つを配置することです。
こんな感じです。

Pythonコードは下記です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pandas as pd
df = pd.read_csv("hogehoge.csv")#ファイル名は、クオテーションで囲んでください。もしtest.csvという名前なら、"hogehoge.csv"は、"test.csv"です

print(df)#読み込んだデータをすべて表示
print(df.head())#最初の5行程度を表示
print(df.shape)#読み込んだデータの行数と列数を表示。100行2列なら(100,2)です

[chat face=”man1″ name=”” align=”left” border=”gray” bg=”none” style=””]全然読み込めないんだけど[/chat]

[chat face=”man1″ name=”” align=”right” border=”gray” bg=”none” style=””]ファイル名のあとに読み込む条件を指定すれば読み込めるよ[/chat]

読み込むことはできましたでしょうか。
整形されたデータの場合はこれで読み込めたはずです。
ところが、実際扱うデータは往々にしてエラーを吐いてしまいます。
その場合、下記の項目をチェックして、読み込む条件を指定して読み込んでみてください。

エラーが出る場合、ポイントは下記になります。列名(header)が先頭にあるかどうか
行番号(index)がデータに含まれるかどうか
列名のないデータだけのファイルかどうか

列名(header)が先頭にない場合の読み込み

この場合、下記のコードで1行目と2行目をスキップして読み込みますので下記になります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pandas as pd
df = pd.read_csv("hogehoge.csv",skiprows=2)#skiprowsの引数を指定することで先頭の2行を無視します

print(df)#読み込んだデータをすべて表示
print(df.head())#最初の5行程度を表示
print(df.shape)#読み込んだデータの行数と列数を表示。100行2列なら(100,2)です

[chat face=”man1″ name=”” align=”left” border=”gray” bg=”none” style=””]df = pd.read_csv(“hogehogehoge.csv”,header=2)と列名を指定しても読み込めます[/chat]

[chat face=”man1″ name=”” align=”right” border=”gray” bg=”none” style=””]0から数えるから、Excelでいう3行目は2で指定するんだね[/chat]

行番号(index)がデータに含まれる場合

この場合は、1列目はindexであると明示的に指定します。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pandas as pd
df = pd.read_csv("hogehoge.csv",index_col=0))#indexは0列目だと明示します

print(df)#読み込んだデータをすべて表示
print(df.head())#最初の5行程度を表示
print(df.shape)#読み込んだデータの行数と列数を表示。100行2列なら(100,2)です
列名がデータにない場合

この場合、1行目からデータであるということを指定する必要があります。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pandas as pd
df = pd.read_csv("hogehoge.csv",header=None))#header=Noneでカラム名はないことを明示します

print(df)#読み込んだデータをすべて表示
print(df.head())#最初の5行程度を表示
print(df.shape)#読み込んだデータの行数と列数を表示。100行2列なら(100,2)です

列名を作成しながら読み込みたい場合、

df=pd.read_csv(“hogehoge.csv”,header=None,names=[“a”,”b”,”c”,”d”])

のようにnamesの引数で指定します

その他の場合

その他さまざまな条件を指定してデータを読み込むことができますが、詳細は公式ドキュメントを参照していただくのがよいと思いますので、最後によく使う指定条件をまとめたいと思います。

◎ファイルが大きすぎる
⇒nrows:nrows=100のように読み込む行数をint型で指定
◎なぜかエラーが起きる
⇒engine:pythonで読み込むかCで読み込むかを指定。engine=”python”と指定すると柔軟に読み込める
◎日本語が文字化けする
⇒encoding:encoding=”shift-jis”で読み込んでみる

よろしくお願いします。
以上、お疲れさまでした。

matplotlibで日本語を表示(python)

matplotlibで日本語を扱いたいとき、フォントをダウンロードして、matplotlibrcファイルを修正して、、みたいな方法が正統派なのかもしれない。
でも職場のパソコンに一斉にそういう設定ができますか?みたいなときがある。

1.フォントをダウンロードして、C:\Users\**\Anaconda3\Lib\site-packages\matplotlib\mpl-data\fonts\ttfの中にコピペをする
2.ファイルのなかにigfont = {‘family’:’IPAexGothic’}という文字列を追加しておく

これだけでよさそう。これなら自動でできそう。
ちなみにつまったところとして、コピペするファイルはipaexg.ttfとipaexm.ttfの2つだということ。一方だけでをコピペするだけだとうまくいきませんでした。フォントのダウンロード先は下記。

https://ipafont.ipa.go.jp/node26

Pythonでwordpressに自動で投稿する(python-wordpress-xmlrpc)

1

絹田
絹田

プラグインやライブラリをPython側に入れるかWordPres側に入れるかで2通りの方法があるよ

自動投稿する際,プラグインやライブラリをPython側に入れるかWordPres側に入れるかで2通りの方法があります.

  • REST:WordPressの「WP REST API」プラグインを使用する
  • XML-RPC:WordPressにデフォルトで備わっているwordpresのxmlrpcのインターフェースを利用する

RESTの方が汎用性は高い一方で、テーマによっては使えないことがあります。XML-rpcの場合は昔からあるので追加設定はいらず安定感はあります。Pythonを使ってxmlrpcでWordPressサイトを操作する場合、python-wordpress-xmlrpcをpipすれば使えるようになります。私はWordPressのプラグインを増やしたくなので後者の方を利用するようにしています。

環境

動作環境はWindows10 64bitでPython3.6.5(Anaconda3.5.1-0)。 Mac Python3.8とXserverのターミナル(Python3.8)からもうまく動作しました。

コード

pip install python-wordpress-xmlrpc

でライブラリを入れました。
(conda install ***だとファイルが見つからなかったので、 Anaconda環境であったがpipで入れました)

あとは下記のコードを実行するだけです。

新規に投稿する場合


# -*- coding: utf-8 -*-
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
def main():
    """
    変数を定義
    """
    id="******"
    password="******"
    #idとpasswordはwordpressの管理画面に入るためのもの

    url="https:***/xmlrpc.php"
    #第3者が閲覧するURLの後ろに/xmlrpc.phpをつける。
    #ワードプレスの管理画面の後ろにつけるとエラーになった

    which="publish"
    #which="draft"
    #下書きに投稿するか本番で投稿するか選択

    """
    クライアントの呼び出しなど
    """
    wp = Client(url, id,password)
    post = WordPressPost()

    """
    実際に投稿する
    """
    post.post_status = which
    post.title = "タイトルをここに書く"
    post.content = "本文をここに書く"
    post.terms_names = {
    "post_tag": ['希望するtag1', '希望するtag2'],
    "category": ['希望するカテゴリー1', '希望するカテゴリー2'],
    }
    #過去に投稿した記事としたい場合、投稿日をここで指定。例として2018年1月1日10時5分10秒に投稿した例を示す。
    post.date=datetime.strptime("2018/1/01 10:05:10","%Y/%m/%d %H:%M:%S")
    wp.call(NewPost(post))

if __name__=="__main__":
   main()

編集する場合

編集をする場合、編集したい記事のIDを取得したあと、その記事に対して操作します。

1.まず編集したい記事のIDを取得


# -*- coding: utf-8 -*-
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPost, GetPosts, NewPost, EditPost

def main():
    id="******"
    password="******"
    #idとpasswordはwordpressの管理画面に入るためのもの

    url="https:***/xmlrpc.php"
    #第3者が閲覧するURLの後ろに/xmlrpc.phpをつける。
    #ワードプレスの管理画面の後ろにつけるとエラーになった

    """
    クライアントの呼び出しなど
    """
    wp = Client(url, id, password)
    post = WordPressPost()
    posts = wp.call(GetPosts({'number': 5}))
    for post in posts:
        print(post.id, post.title,str(post.terms[0]))

if __name__=="__main__":
   main()

もし編集したい記事が決まっている場合、その記事の編集画面にいくとURLにIDが表示されますのでそちらを利用することも可能です。

2. 記事を編集する

上記で記事IDを調べて、その記事に対して操作します。pidが編集したい記事のID(post_id)です。


# -*- coding: utf-8 -*-
import time
from datetime import datetime
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods.posts import GetPost, GetPosts, NewPost, EditPost
def main():
    id="******"
    password="******"
    #idとpasswordはwordpressの管理画面に入るためのもの

    url="https:***/xmlrpc.php"
    #第3者が閲覧するURLの後ろに/xmlrpc.phpをつける。
    #ワードプレスの管理画面の後ろにつけるとエラーになった

    """
    クライアントの呼び出しなど
    """
    wp = Client(url, id, password)

    pid = 1030
    post = wp.call(GetPost(pid))

    post.post_status = "publish"
    post.content = "content"
    post.terms_names = {
    "post_tag": ['tag1'],
    "category": ['diary',],
    }
    ret = wp.call(EditPost(pid, post))

if __name__=="__main__":
    main()

動作環境の注意

手元のPCはWIndowsでも Macでも動作確認しています。Xserverのターミナルからもうまく動作しました。しかし、以前Google Cloud PlatformのCloud functionsでデプロイした場合はできなかった記憶があります。AWS lamdbaなどでもエラーが起きる可能性があるのでローカルで動作させる事をお勧めします。

動作しない場合

・siteGuardなどセキュリティ系のプラグインを入れると、デフォルトでxmlrpcをオフにしますので、解除が必要です

・Xserverなど一部のレンタルサーバでは意図的にデフォルト でアクセスをOFFにしていますので管理画面から設定変更が必要です

siteguardの設定をオフにする

ダッシュ画面の左下からsiteguardを選択します。その中にXMMRPC防御という項目があるのでクリックします。

左上の部分でOFFを選択します。

Xserverの場合

xserverの場合、公式が丁寧に説明してくれているのでこちらを見れば大丈夫だと思います。

https://www.xserver.ne.jp/news_detail.php?view_id=6875

https://www.xserver.ne.jp/manual/man_server_wpsecurity.php#link-b02

絹田
絹田

読んでくれてありがとう.これからもよろしくね

pythonのリストをmap、filter、lambdaで操作する

1

操作対象のリストを作成

>>> lst = [i for i in range(10)]
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

map関数で全体に対して操作

こういうリストがあったときに全体に対して操作するならこれ

>>> lst2 = list(map(lambda e:e*2,lst))
>>> lst2
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

python3では、map関数が返すものはmap objectなのでlistへ変換する必要がある。

filter関数で特定のものを抽出

>>> lst2 = list(filter(lambda e:e%2==0,lst))
>>> lst2
[0, 2, 4, 6, 8]