折腾:
【未解决】用Python通过WordPress的REST的API发布文章post
期间,突然想到,还要考虑如何把图片加进来:
通过看posts返回结果:
<img src=\"https://www.crifan.com/files/pic/uploads/2020/03/6e196a1b6bc817e6e91a9dc44c88aca7.jpg\" /></p>\n<p>【总结】</p>\n<p>目前最新版:</p>\n<p>央行MLF 商业银行LPR 地方政府加点 个人房贷利率 关系</p>\n<p><img src=\"https://www.crifan.com/files/pic/uploads/2020/03/a0ada3f4bde7286a8be2838cf298c44d.jpg\" />
此处是已上传后,得到了link后,加到html中的。
所以要再去看,如何上传图片
看起来像是:
-》
结果也是要:
就像发布post一样,上传图片也是单独的api
也是要一堆参数的。
不过此处尽量简化参数值
所以先去试试,上传图片
date_gmt
看到:meta Meta fields
-》
meta object
Meta fields. Context: view, edit
突然想到:去看看是不是:其实此处图片只是meta,而不是Media
结果好像没有meta的post接口?
WordPress rest api meta
WP REST API create post with meta | WordPress.org
Extending the REST API for protected meta | WordPress.org
Updating product metadata using REST API | WordPress.org
好像meta不是图片二进制
所以重新搜:
wordpress rest api upload image
def restImgUL(imgPath): url='http://xxxxxxxxxxxx.com/wp-json/wp/v2/media' data = open(imgPath, 'rb').read() fileName = os.path.basename(imgPath) res = requests.post(url='http://xxxxxxxxxxxxx.com/wp-json/wp/v2/media', data=data, headers={ 'Content-Type': 'image/jpg','Content-Disposition' : 'attachment; filename=%s'% fileName}, auth=('authname', 'authpass')) # pp = pprint.PrettyPrinter(indent=4) ## print it pretty. # pp.pprint(res.json()) #this is nice when you need it newDict=res.json() newID= newDict.get('id') link = newDict.get('guid').get("rendered") print newID, link return (newID, link)
就是media的接口
data直接是binary data
去试试
$imagetype = array( 'bmp' => 'image/bmp', 'gif' => 'image/gif', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'png' => 'image/png', 'tif' => 'image/tiff', 'tiff' => 'image/tiff' );
Uploading image from the media api | WordPress.org
Upload image API REST | WordPress.org
但是官网竟然没有说,具体如何
POST /wp/v2/media
传递data方面的参数以及其他的headers去上传图片
这里好像说是
Content-type是application/json ?
-》
”Uploading images is a two step process:
1. POST the data to /wp/v2/media – this can either be as the request body, or in multipart format. This will upload the file, and give you a 201 Created response with a Location header. This header points to the post object for the attachment that has just been created.
2. PUT the post data to the endpoint returned in the Location header (which will look something like /wp/v2/media/{id}).
Your request here appears to be trying to sideload an image (that is, upload from a URL). This is not possible via the API; you need to fetch the image yourself, and send the data to the API yourself.“
分2步
wordpress rest api upload image python
user_id = "[你的作者使用者名稱]" user_passwd = 'xxxX xxxX xxxX xxxX xxxX xxxX' end_point_url_img = 'https://[你的 WordPress 網域]/wp-json/wp/v2/media' imgname = "./[圖片實際名稱,建議用英文,必須要加上副檔名]" feauturedfilename, feauturedfile_extension = os.path.splitext(imgname) if feauturedfile_extension == "svg": contenimg = 'image/svg' if feauturedfile_extension == "png": contenimg = 'image/png' if feauturedfile_extension == "jpg" or "jpeg": contenimg = 'image/jpg' headers = { 'Content-Type': contenimg,'Content-Disposition' : 'attachment; filename=%s'%imgname} post = { 'caption': '[圖片會顯示在文章的標示說明]', 'description': '[你的圖片詳細描述內容]' } data = open(imgname, 'rb').read() response = requests.post(url=end_point_url_img, data=data, headers=headers, json=post, auth=(user_id, user_passwd))
看不来不错
python – 如何在python中使用wordpress REST api上传图像? – 堆栈内存溢出
https://stackoom.com/question/2yGLQ/如何在python中使用wordpress-REST-api上传图像
参考:
好像可以同时传递data和json的?
requests post data json
>>> import json >>> url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, data=json.dumps(payload))
或:
>>> url = 'https://api.github.com/some/endpoint' >>> payload = {'some': 'data'} >>> r = requests.post(url, json=payload)
-》正常是自己把dict的用dict转换成json字符串,给data
-》或者把dict传递给json,requests自动帮你转换成json
->说明不是两者同时传递的参数,而是二选一
gImageFormatToSuffix = { "BMP": "bmp", "PNG": "png", "JPEG": "jpg", "TIFF": "tif", } gImageSuffixToMime = { 'bmp': 'image/bmp', 'gif': 'image/gif', 'jpe': 'image/jpeg', 'jpeg': 'image/jpeg', 'jpg': 'image/jpeg', 'png': 'image/png', 'tif': 'image/tiff', 'tiff': 'image/tiff', # 'svg': 'image/svg', } def uploadImage(imgResource): """ Upload image resource to wordpress """ imgData = imgResource.data imgBytes = imgData.body imgDataSize = imgData.size # guid:'f6956c30-ef0b-475f-a2b9-9c2f49622e35' imgGuid = imgResource.guid logging.info("imgGuid=%s, imgDataSize=%s", imgGuid, imgDataSize) curImg = utils.bytesToImage(imgBytes) logging.info("curImg=%s", curImg) # for debug curImg.show() imgFormat = curImg.format # 'PNG' imgSuffix = gImageFormatToSuffix[imgFormat] # 'png' imgMime = gImageSuffixToMime[imgSuffix] # 'image/png' # curDatetimeStr = utils.getCurDatetimeStr() # '20200307_173141' processedGuid = imgGuid.replace("-", "") # 'f6956c30ef0b475fa2b99c2f49622e35' # imgeFilename = "%s.%s" % (curDatetimeStr, imgSuffix) # '20200307_173141.png' imgeFilename = "%s.%s" % (processedGuid, imgSuffix) # 'f6956c30ef0b475fa2b99c2f49622e35.png' authValue = "Bearer %s" % JWT_TOKEN curHeaders = { "Authorization": authValue, "Content-Type": imgMime, 'Content-Disposition': 'attachment; filename=%s' % imgeFilename, } logging.info("curHeaders=%s", curHeaders) # curHeaders={'Authorization': 'Bearer eyJ0xxxyyy.zzzB4', 'Content-Type': 'image/png', 'Content-Disposition': 'attachment; filename=f6956c30ef0b475fa2b99c2f49622e35.png'} uploadImgUrl = API_MEDIA resp = requests.post(uploadImgUrl, headers=curHeaders, data=imgBytes) logging.info("resp=%s", resp)
单独调试,结果执行都要等半天:
要么上传图片慢,要么是本身crifan.com访问起来很慢
结果等了几分钟了,还没结束,说明有问题
按道理即使是超时了,也该超时结束了
如果是访问crifan.com慢,就要去想办法加上代理了:
【未解决】给Python的requests加上代理访问WordPress的REST的api
暂时加代理没成功。
算了,去掉代理,再多试试几次,看看结果,结果后来调试可以返回了:
现在可以返回结果了。不过又是别的错误:
【已解决】WordPress的rest的api访问报错:403 jwt_auth_bad_config JWT is not configurated properly
很高兴,竟然返回201,表示创建成功了:
'{"id":70393,"date":"2020-03-07T18:43:47","date_gmt":"2020-03-07T10:43:47","guid":{"rendered":"https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png","raw":"https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png"},"modified":"2020-03-07T18:43:47","modified_gmt":"2020-03-07T10:43:47","slug":"f6956c30ef0b475fa2b99c2f49622e35","status":"inherit","type":"attachment","link":"https:\\/\\/www.crifan.com\\/f6956c30ef0b475fa2b99c2f49622e35\\/","title":{"raw":"f6956c30ef0b475fa2b99c2f49622e35","rendered":"f6956c30ef0b475fa2b99c2f49622e35"},"author":1,"comment_status":"open","ping_status":"closed","template":"","meta":[],"permalink_template":"https:\\/\\/www.crifan.com\\/?attachment_id=70393","generated_slug":"f6956c30ef0b475fa2b99c2f49622e35","description":{"raw":"","rendered":"<p class=\\"attachment\\"><a href=\'https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png\'><img width=\\"480\\" height=\\"104\\" src=\\"https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png\\" class=\\"attachment-medium size-medium\\" alt=\\"\\" \\/><\\/a><\\/p>\\n<p>\\u8f6c\\u8f7d\\u8bf7\\u6ce8\\u660e\\uff1a<a href=\\"https:\\/\\/www.crifan.com\\">\\u5728\\u8def\\u4e0a<\\/a> » <a href=\\"https:\\/\\/www.crifan.com\\/f6956c30ef0b475fa2b99c2f49622e35\\/\\">f6956c30ef0b475fa2b99c2f49622e35<\\/a><\\/p>"},"caption":{"raw":"","rendered":"<p>\\u8f6c\\u8f7d\\u8bf7\\u6ce8\\u660e\\uff1a\\u5728\\u8def\\u4e0a » f6956c30ef0b475fa2b99c2f49622e35<\\/p>\\n"},"alt_text":"","media_type":"image","mime_type":"image\\/png","media_details":{"width":480,"height":104,"file":"2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png","sizes":{"post-thumbnail":{"file":"f6956c30ef0b475fa2b99c2f49622e35-220x104.png","width":220,"height":104,"mime_type":"image\\/png","source_url":"https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35-220x104.png"},"full":{"file":"f6956c30ef0b475fa2b99c2f49622e35.png","width":480,"height":104,"mime_type":"image\\/png","source_url":"https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png"}},"image_meta":{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","keywords":[]}},"post":null,"source_url":"https:\\/\\/www.crifan.com\\/files\\/pic\\/uploads\\/2020\\/03\\/f6956c30ef0b475fa2b99c2f49622e35.png","missing_image_sizes":[],"_links":{"self":[{"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/media\\/70393"}],"collection":[{"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/media"}],"about":[{"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/types\\/attachment"}],"author":[{"embeddable":true,"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/users\\/1"}],"replies":[{"embeddable":true,"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/comments?post=70393"}],"wp:action-unfiltered-html":[{"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/media\\/70393"}],"wp:action-assign-author":[{"href":"https:\\/\\/www.crifan.com\\/wp-json\\/wp\\/v2\\/media\\/70393"}],"curies":[{"name":"wp","href":"https:\\/\\/api.w.org\\/{rel}","templated":true}]}}'
格式化后,容易看懂:
{ "id": 70393, "date": "2020-03-07T18:43:47", "date_gmt": "2020-03-07T10:43:47", "guid": { "rendered": "https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png", "raw": "https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png" }, "modified": "2020-03-07T18:43:47", "modified_gmt": "2020-03-07T10:43:47", "slug": "f6956c30ef0b475fa2b99c2f49622e35", "status": "inherit", "type": "attachment", "link": "https://www.crifan.com/f6956c30ef0b475fa2b99c2f49622e35/", "title": { "raw": "f6956c30ef0b475fa2b99c2f49622e35", "rendered": "f6956c30ef0b475fa2b99c2f49622e35" }, "author": 1, "comment_status": "open", "ping_status": "closed", "template": "", "meta": [], "permalink_template": "https://www.crifan.com/?attachment_id=70393", "generated_slug": "f6956c30ef0b475fa2b99c2f49622e35", "description": { "raw": "", "rendered": "<p class=" attachment "><a href='https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png'><img width=" 480 " height=" 104 " src=" https: //www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png" class="attachment-medium size-medium" alt="" /></a></p>\\n<p>\\u8f6c\\u8f7d\\u8bf7\\u6ce8\\u660e\\uff1a<a href="https://www.crifan.com">\\u5728\\u8def\\u4e0a</a> » <a href="https://www.crifan.com/f6956c30ef0b475fa2b99c2f49622e35/">f6956c30ef0b475fa2b99c2f49622e35</a></p>"},"caption":{"raw":"","rendered":"<p>\\u8f6c\\u8f7d\\u8bf7\\u6ce8\\u660e\\uff1a\\u5728\\u8def\\u4e0a » f6956c30ef0b475fa2b99c2f49622e35</p>\\n"},"alt_text":"","media_type":"image","mime_type":"image/png","media_details":{"width":480,"height":104,"file":"2020/03/f6956c30ef0b475fa2b99c2f49622e35.png","sizes":{"post-thumbnail":{"file":"f6956c30ef0b475fa2b99c2f49622e35-220x104.png","width":220,"height":104,"mime_type":"image/png","source_url":"https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35-220x104.png"},"full":{"file":"f6956c30ef0b475fa2b99c2f49622e35.png","width":480,"height":104,"mime_type":"image/png","source_url":"https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png"}},"image_meta":{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0","keywords":[]}},"post":null,"source_url":"https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png","missing_image_sizes":[],"_links":{"self":[{"href":"https://www.crifan.com/wp-json/wp/v2/media/70393"}],"collection":[{"href":"https://www.crifan.com/wp-json/wp/v2/media"}],"about":[{"href":"https://www.crifan.com/wp-json/wp/v2/types/attachment"}],"author":[{"embeddable":true,"href":"https://www.crifan.com/wp-json/wp/v2/users/1"}],"replies":[{"embeddable":true,"href":"https://www.crifan.com/wp-json/wp/v2/comments?post=70393"}],"wp:action-unfiltered-html":[{"href":"https://www.crifan.com/wp-json/wp/v2/media/70393"}],"wp:action-assign-author":[{"href":"https://www.crifan.com/wp-json/wp/v2/media/70393"}],"curies":[{"name":"wp","href":"https://api.w.org/{rel}","templated":true}]}}
是可以打开图片的
说明此处上传图片是可以了。
【总结】
此处用代码:
HOST = "https://www.crifan.com" API_MEDIA = HOST + "/wp-json/wp/v2/media" JWT_TOKEN = "eyJxxxxxxxxjLYB4" imgMime = gImageSuffixToMime[imgSuffix] # 'image/png' imgeFilename = "%s.%s" % (processedGuid, imgSuffix) # 'f6956c30ef0b475fa2b99c2f49622e35.png' authValue = "Bearer %s" % JWT_TOKEN curHeaders = { "Authorization": authValue, "Content-Type": imgMime, 'Content-Disposition': 'attachment; filename=%s' % imgeFilename, } logging.info("curHeaders=%s", curHeaders) # curHeaders={'Authorization': 'Bearer eyJ0xxxyyy.zzzB4', 'Content-Type': 'image/png', 'Content-Disposition': 'attachment; filename=f6956c30ef0b475fa2b99c2f49622e35.png'} uploadImgUrl = API_MEDIA resp = requests.post( uploadImgUrl, # proxies=cfgProxies, headers=curHeaders, data=imgBytes, )
即可:
返回201,表示created,media创建成功
返回json中:
{ "id": 70393, "date": "2020-03-07T18:43:47", "date_gmt": "2020-03-07T10:43:47", "guid": { "rendered": "https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png", "raw": "https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png" }, ...
guid的rendered就是图片地址:
https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png
【后记】
已回复帖子了:
【后记2】
也看到api上传图片的
assert os.path.exists(img_path), "img should exist" data = open(img_path, 'rb').read() filename = os.path.basename(img_path) _, extension = os.path.splitext(filename) headers = { 'cache-control': 'no-cache', 'content-disposition': 'attachment; filename=%s' % filename, 'content-type': 'image/%s' % extension } endpoint = "/media" return wpapi.post(endpoint, data, headers=headers)
也值得参考。
【后记3】
在自己的crifan.com的WordPress管理后台看到了,上传的media的图片:
点击后可以看到详情:
对应信息是:
文件名: f6956c30ef0b475fa2b99c2f49622e35.png 文件类型: image/png 上传于: 2020年3月13日 文件大小: 32 KB 分辨率: 480×104像素 标题: f6956c30ef0b475fa2b99c2f49622e35 上传者为crifan 复制链接:https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png
点击查看附件页面,进入:
-》即每个media,还是有单独的页面的。
-》之前都不知道。现在知道了。
【后记20210321】
已回复帖子
最新代码详见: