I have a page that I need to periodically update the file location for a link to point at a new file. Trying to do this via a Python script using requests
.
I've got authentication set up via 'Application Passwords' plugin, and I'm able to download a json from the api for the page in question. I have a pre-built string that contains the new file location, ready to go. I extract the page content, specifically the 'rendered' version, as a string. I do a quick replace()
on that string between two known tags (<h4>
) and then reload the modified 'rendered' page content back into the json, and upload it back to the endpoint, again using requests()
.
When it's all said and done, I'm getting no errors from the script, a status code of 200... but nothing changes on the page.
Furthermore, I'm finding the following in the error log:
[21-Aug-2019 00:12:51 UTC] PHP Warning: Invalid argument supplied for foreach() in /home1/example/public_html/wp-includes/rest-api/class-wp-rest-request.php on line 778
Not exactly sure what that means, but I'm assuming it's not good.
import base64, json, requests
user = 'admin'
pythonapp = 'QUDM PYFn xfyK 9Hhe Ayf2 hk6k'
url = ''
data_string = user + ':' + pythonapp
token = base64.b64encode(data_string.encode())
headers = {'Authorization':'Basic ' + token.decode('utf8')}
newsletterURL = '.pdf'
oldH4 = '<h4><a href=".pdf" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Click here to download the newsletter!!!</a></h4>'
newH4 = '<h4><a href="' + newsletterURL + '" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Click here to download the newsletter!!!</a></h4>'
# Download the current Newsletter page
r = requests.get(url + '/pages/6', headers=headers)
tmp = r.json()
Pretty sure the code up to this point works as intended/expected; obviously it's been somewhat modified to be a stand-alone example vs. part of the larger script.
oldPageContent = tmp['content']['rendered']
# print(oldPageContent.partition('</h4>')[0])
newPageContent = oldPageContent.replace(oldH4, newH4)
# print(newPageContent.partition('</h4>')[0])
tmp['content']['rendered'] = newPageContent
# print(tmp['content']['rendered'].partition('</h4>')[0])
r = requests.post(url + '/pages/6', headers=headers, json=tmp)
# print(json.loads(r.content.decode('utf8'))['content']['rendered'].partition('</h4>')
Here I'm attempting to replace the specific URL inside the body content, reassemble things, and upload the whole thing back to the
"content": {
"rendered": "\n<h4><a href=\".pdf\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Click here to download the newsletter!!!</a></h4>\n\n\n\n<p>Submissions for the newsletter are always welcome. Space is somewhat limited so keep \u2019em short and sweet!",
"protected": false
}
This is an example of the specific field that I'm trying to extract from the content of the page, update, and upload.
Kinda thinking maybe I should be using json.dumps/loads
to get at ['content']['rendered']
rather than just r.json()
? Though when I print out the resulting strings, they sure look like right...
Any ideas/suggestions for updating a page via the REST api? Or am I going about this completely wrong?
Update:
After the excellent help from @SallyCJ, this is the final form of what I ended up with, in case it helps anyone else down the road:
import base64, json, re, requests
user = 'admin'
pythonapp = 'QUDM PYFn xfyK 9Hhe Ayf2 hk6k'
url = ''
data_string = user + ':' + pythonapp
token = base64.b64encode(data_string.encode())
headers = {'Authorization':'Basic ' + token.decode('utf8')}
# Temporary URL for the sake of testing
newsletterURL = '.pdf'
# Download the current Newsletter page
r = requests.get(url + '/pages/6', headers=headers)
# Extract the actual page content from all the rest of the API data
data = r.json()
content = data['content']['rendered']
# Find the URL for the download in 'content', and replace it with the new URL
regex = r"(http(s)?)://(www.)?(example\/wp-content/uploads\/).+(pdf)"
newContent = re.sub(regex, newsletterURL,content)
# Create a new data payload using the updated 'content'
data = {"content": newContent}
# Upload it back to the site
r = requests.post(url + '/pages/6', headers=headers, json=data)
I have a page that I need to periodically update the file location for a link to point at a new file. Trying to do this via a Python script using requests
.
I've got authentication set up via 'Application Passwords' plugin, and I'm able to download a json from the api for the page in question. I have a pre-built string that contains the new file location, ready to go. I extract the page content, specifically the 'rendered' version, as a string. I do a quick replace()
on that string between two known tags (<h4>
) and then reload the modified 'rendered' page content back into the json, and upload it back to the endpoint, again using requests()
.
When it's all said and done, I'm getting no errors from the script, a status code of 200... but nothing changes on the page.
Furthermore, I'm finding the following in the error log:
[21-Aug-2019 00:12:51 UTC] PHP Warning: Invalid argument supplied for foreach() in /home1/example/public_html/wp-includes/rest-api/class-wp-rest-request.php on line 778
Not exactly sure what that means, but I'm assuming it's not good.
import base64, json, requests
user = 'admin'
pythonapp = 'QUDM PYFn xfyK 9Hhe Ayf2 hk6k'
url = 'https://example/wp-json/wp/v2'
data_string = user + ':' + pythonapp
token = base64.b64encode(data_string.encode())
headers = {'Authorization':'Basic ' + token.decode('utf8')}
newsletterURL = 'http://www.example/wp-content/uploads/2019/08/lorem-ipsum.pdf'
oldH4 = '<h4><a href="http://www.example/wp-content/uploads/2019/08/NCWGC-2019-8.pdf" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Click here to download the newsletter!!!</a></h4>'
newH4 = '<h4><a href="' + newsletterURL + '" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">Click here to download the newsletter!!!</a></h4>'
# Download the current Newsletter page
r = requests.get(url + '/pages/6', headers=headers)
tmp = r.json()
Pretty sure the code up to this point works as intended/expected; obviously it's been somewhat modified to be a stand-alone example vs. part of the larger script.
oldPageContent = tmp['content']['rendered']
# print(oldPageContent.partition('</h4>')[0])
newPageContent = oldPageContent.replace(oldH4, newH4)
# print(newPageContent.partition('</h4>')[0])
tmp['content']['rendered'] = newPageContent
# print(tmp['content']['rendered'].partition('</h4>')[0])
r = requests.post(url + '/pages/6', headers=headers, json=tmp)
# print(json.loads(r.content.decode('utf8'))['content']['rendered'].partition('</h4>')
Here I'm attempting to replace the specific URL inside the body content, reassemble things, and upload the whole thing back to the
"content": {
"rendered": "\n<h4><a href=\"http://www.example/wp-content/uploads/2019/08/NCWGC-2019-8.pdf\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Click here to download the newsletter!!!</a></h4>\n\n\n\n<p>Submissions for the newsletter are always welcome. Space is somewhat limited so keep \u2019em short and sweet!",
"protected": false
}
This is an example of the specific field that I'm trying to extract from the content of the page, update, and upload.
Kinda thinking maybe I should be using json.dumps/loads
to get at ['content']['rendered']
rather than just r.json()
? Though when I print out the resulting strings, they sure look like right...
Any ideas/suggestions for updating a page via the REST api? Or am I going about this completely wrong?
Update:
After the excellent help from @SallyCJ, this is the final form of what I ended up with, in case it helps anyone else down the road:
import base64, json, re, requests
user = 'admin'
pythonapp = 'QUDM PYFn xfyK 9Hhe Ayf2 hk6k'
url = 'https://example/wp-json/wp/v2'
data_string = user + ':' + pythonapp
token = base64.b64encode(data_string.encode())
headers = {'Authorization':'Basic ' + token.decode('utf8')}
# Temporary URL for the sake of testing
newsletterURL = 'http://www.example/wp-content/uploads/2019/08/lorem-ipsum.pdf'
# Download the current Newsletter page
r = requests.get(url + '/pages/6', headers=headers)
# Extract the actual page content from all the rest of the API data
data = r.json()
content = data['content']['rendered']
# Find the URL for the download in 'content', and replace it with the new URL
regex = r"(http(s)?)://(www.)?(example\/wp-content/uploads\/).+(pdf)"
newContent = re.sub(regex, newsletterURL,content)
# Create a new data payload using the updated 'content'
data = {"content": newContent}
# Upload it back to the site
r = requests.post(url + '/pages/6', headers=headers, json=data)
Share
Improve this question
edited Aug 29, 2019 at 9:39
memilanuk
asked Aug 22, 2019 at 0:33
memilanukmemilanuk
1131 silver badge5 bronze badges
4
- 1 Perhaps double-checking the relevant endpoint/route reference would help. But I'm guessing you're not sending the proper parameters when updating the page.. – Sally CJ Commented Aug 22, 2019 at 12:39
- Unfortunately the examples in that reference are a little... sparse... on details, at least for updating the page. That said, I think you're probably correct; I did some more poking around, and I can do other operations via the api without any difficulty, just not updating that page. Not sure what I'm not doing right, though... – memilanuk Commented Aug 23, 2019 at 19:14
- 1 Well, if you can show your code.. or the request parameters, then maybe I can help? – Sally CJ Commented Aug 24, 2019 at 14:25
- @SallyCJ put the code and commentary in the original post. Thanks for the help! – memilanuk Commented Aug 25, 2019 at 21:53
1 Answer
Reset to default 1The problem is with your POST
request, where the content
property should be a plain string and not an object. You should also send just the data that you want to change.
When updating a Page (i.e. a post of the type page
), you should provide a JSON-encoded or URL-encoded string containing one or more of the properties/parameters as listed here.
Examples using cURL from the command line prompt:
URL-encoded (
Content-Type
header isapplication/x-www-form-urlencoded
):curl -d "title=New%20Title!&content=New%20Content%3F" -X POST https://example/wp-json/wp/v2/pages/9 --user "admin:QUDM PYFn xfyK 9Hhe Ayf2 hk6k"
JSON-encoded
curl -H "Content-Type: application/json" -d "{\"title\":\"New Title!\",\"content\":\"New Content?\"}" -X POST https://example/wp-json/wp/v2/pages/9 --user "admin:QUDM PYFn xfyK 9Hhe Ayf2 hk6k"
So in your code:
This line:
tmp['content']['rendered'] = newPageContent
should be:
tmp = { 'content': newPageContent }
but you can of course add other properties that you want to change; e.g.
title
andstatus
.
And (despite that I'm not a Python expert), you can use the example below as a reference when creating/retrieving/updating/deleting a Page:
import base64, json, requests
user = 'admin'
pythonapp = 'QUDM PYFn xfyK 9Hhe Ayf2 hk6k'
url = 'https://example/wp-json/wp/v2'
data_string = user + ':' + pythonapp
token = base64.b64encode( data_string.encode() )
headers = { 'Authorization': 'Basic ' + token.decode( 'utf8' ) }
# Create a Page.
data = { 'title': 'Testing from Python' }
r = requests.post( url + '/pages/', headers=headers, json=data )
data = r.json()
page_id = str( data['id'] )
print 'Page created. ID: ' + page_id
# Retrieve the Page.
r = requests.get( url + '/pages/' + page_id, headers=headers )
data = r.json()
title = data['title']['rendered']
print 'Page #' + page_id + ' retrieved. The title is: ' + title
# Update the Page.
data = { 'content': 'New content here' }
r = requests.post( url + '/pages/' + page_id, headers=headers, json=data )
data = r.json()
content = data['content']['rendered']
print 'Page #' + page_id + ' updated. Content set to: ' + content
# Delete the Page.
r = requests.delete( url + '/pages/' + page_id, headers=headers )
data = r.json()
print 'Page #' + page_id + ' moved to the Trash. (Well, it should be...)'
print 'The Page "status" is ' + data['status']
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745202661a4616419.html
评论列表(0条)