Saving response from Requests to file
Question:
I’m using Requests to upload a PDF to an API. It is stored as “response” below. I’m trying to write that out to Excel.
import requests
files = {'f': ('1.pdf', open('1.pdf', 'rb'))}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
file = open("out.xls", "w")
file.write(response)
file.close()
I’m getting the error:
file.write(response)
TypeError: expected a character buffer object
Answers:
As Peter already pointed out:
In [1]: import requests
In [2]: r = requests.get('https://api.github.com/events')
In [3]: type(r)
Out[3]: requests.models.Response
In [4]: type(r.content)
Out[4]: str
You may also want to check r.text
.
Also: https://2.python-requests.org/en/latest/user/quickstart/
You can use the response.text
to write to a file:
import requests
files = {'f': ('1.pdf', open('1.pdf', 'rb'))}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
with open("resp_text.txt", "w") as file:
file.write(response.text)
I believe all the existing answers contain the relevant information, but I would like to summarize.
The response object that is returned by requests
get and post operations contains two useful attributes:
Response attributes
response.text
– Contains str
with the response text.
response.content
– Contains bytes
with the raw response content.
You should choose one or other of these attributes depending on the type of response you expect.
- For text-based responses (html, json, yaml, etc) you would use
response.text
- For binary-based responses (jpg, png, zip, xls, etc) you would use
response.content
.
Writing response to file
When writing responses to file you need to use the open function with the appropriate file write mode.
- For text responses you need to use
"w"
– plain write mode.
- For binary responses you need to use
"wb"
– binary write mode.
Examples
Text request and save
# Request the HTML for this web page:
response = requests.get("https://stackoverflow.com/questions/31126596/saving-response-from-requests-to-file")
with open("response.txt", "w") as f:
f.write(response.text)
Binary request and save
# Request the profile picture of the OP:
response = requests.get("https://i.stack.imgur.com/iysmF.jpg?s=32&g=1")
with open("response.jpg", "wb") as f:
f.write(response.content)
Answering the original question
The original code should work by using wb
and response.content
:
import requests
files = {'f': ('1.pdf', open('1.pdf', 'rb'))}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
file = open("out.xls", "wb")
file.write(response.content)
file.close()
But I would go further and use the with
context manager for open
.
import requests
with open('1.pdf', 'rb') as file:
files = {'f': ('1.pdf', file)}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
with open("out.xls", "wb") as file:
file.write(response.content)
I’m using Requests to upload a PDF to an API. It is stored as “response” below. I’m trying to write that out to Excel.
import requests
files = {'f': ('1.pdf', open('1.pdf', 'rb'))}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
file = open("out.xls", "w")
file.write(response)
file.close()
I’m getting the error:
file.write(response)
TypeError: expected a character buffer object
As Peter already pointed out:
In [1]: import requests
In [2]: r = requests.get('https://api.github.com/events')
In [3]: type(r)
Out[3]: requests.models.Response
In [4]: type(r.content)
Out[4]: str
You may also want to check r.text
.
Also: https://2.python-requests.org/en/latest/user/quickstart/
You can use the response.text
to write to a file:
import requests
files = {'f': ('1.pdf', open('1.pdf', 'rb'))}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
with open("resp_text.txt", "w") as file:
file.write(response.text)
I believe all the existing answers contain the relevant information, but I would like to summarize.
The response object that is returned by requests
get and post operations contains two useful attributes:
Response attributes
response.text
– Containsstr
with the response text.response.content
– Containsbytes
with the raw response content.
You should choose one or other of these attributes depending on the type of response you expect.
- For text-based responses (html, json, yaml, etc) you would use
response.text
- For binary-based responses (jpg, png, zip, xls, etc) you would use
response.content
.
Writing response to file
When writing responses to file you need to use the open function with the appropriate file write mode.
- For text responses you need to use
"w"
– plain write mode. - For binary responses you need to use
"wb"
– binary write mode.
Examples
Text request and save
# Request the HTML for this web page:
response = requests.get("https://stackoverflow.com/questions/31126596/saving-response-from-requests-to-file")
with open("response.txt", "w") as f:
f.write(response.text)
Binary request and save
# Request the profile picture of the OP:
response = requests.get("https://i.stack.imgur.com/iysmF.jpg?s=32&g=1")
with open("response.jpg", "wb") as f:
f.write(response.content)
Answering the original question
The original code should work by using wb
and response.content
:
import requests
files = {'f': ('1.pdf', open('1.pdf', 'rb'))}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
file = open("out.xls", "wb")
file.write(response.content)
file.close()
But I would go further and use the with
context manager for open
.
import requests
with open('1.pdf', 'rb') as file:
files = {'f': ('1.pdf', file)}
response = requests.post("https://pdftables.com/api?&format=xlsx-single",files=files)
response.raise_for_status() # ensure we notice bad responses
with open("out.xls", "wb") as file:
file.write(response.content)