标签归档:curl

如何使用python执行curl命令

问题:如何使用python执行curl命令

我想在python中执行curl命令。

通常,我只需要在终端中输入命令并按回车键即可。但是,我不知道它如何在python中工作。

该命令显示如下:

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

有一个request.json文件要发送以获得响应。

我搜索了很多,感到困惑。尽管我无法完全理解,但我还是尝试编写了一段代码。没用

import pycurl
import StringIO

response = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere')
c.setopt(c.WRITEFUNCTION, response.write)
c.setopt(c.HTTPHEADER, ['Content-Type: application/json','Accept-Charset: UTF-8'])
c.setopt(c.POSTFIELDS, '@request.json')
c.perform()
c.close()
print response.getvalue()
response.close()

错误信息为“解析错误”。有人可以告诉我如何解决吗?或如何正确获取服务器的响应?

I want to execute a curl command in python.

Usually, I just need enter the command in terminal and press return key. However, I don’t know how it works in python.

The command shows below:

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

There is a request.json file to be sent to get response.

I searched a lot and got confused. I tried to write a piece of code, although I could not fully understand. It didn’t work.

import pycurl
import StringIO

response = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere')
c.setopt(c.WRITEFUNCTION, response.write)
c.setopt(c.HTTPHEADER, ['Content-Type: application/json','Accept-Charset: UTF-8'])
c.setopt(c.POSTFIELDS, '@request.json')
c.perform()
c.close()
print response.getvalue()
response.close()

The error message is ‘Parse Error’.Can anyone tell me how to fix it? or how to get response from the sever correctly?


回答 0

为了简单起见,也许您应该考虑使用Requests库。

带有json响应内容的示例如下所示:

import requests
r = requests.get('https://github.com/timeline.json')
r.json()

如果您需要更多信息,请在“ 快速入门”部分中找到许多可行的示例。

编辑:

对于您特定的curl翻译:

import requests
url = 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere'
payload = open("request.json")
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=payload, headers=headers)

For sake of simplicity, maybe you should consider using the Requests library.

An example with json response content would be something like:

import requests
r = requests.get('https://github.com/timeline.json')
r.json()

If you look for further information, in the Quickstart section, they have lots of working examples.

EDIT:

For your specific curl translation:

import requests
url = 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere'
payload = open("request.json")
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=payload, headers=headers)

回答 1

只要使用这个网站。它将任何curl命令转换为Python,Node.js,PHP,R或Go。

例:

curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/asdfasdfasdf

在Python中成为这个

import requests

headers = {
    'Content-type': 'application/json',
}

data = '{"text":"Hello, World!"}'

response = requests.post('https://hooks.slack.com/services/asdfasdfasdf', headers=headers, data=data)

Just use this website. It’ll convert any curl command into Python, Node.js, PHP, R, or Go.

Example:

curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/asdfasdfasdf

Becomes this in Python,

import requests

headers = {
    'Content-type': 'application/json',
}

data = '{"text":"Hello, World!"}'

response = requests.post('https://hooks.slack.com/services/asdfasdfasdf', headers=headers, data=data)

回答 2

import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json

也许?

如果您要发送文件

files = {'request_file': open('request.json', 'rb')}
r = requests.post(url, files=files)
print r.text, print r.json

啊,谢谢@LukasGraf现在,我更好地了解了他的原始代码在做什么

import requests,json
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
my_json_data = json.load(open("request.json"))
req = requests.post(url,data=my_json_data)
print req.text
print 
print req.json # maybe? 
import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json

maybe?

if you are trying to send a file

files = {'request_file': open('request.json', 'rb')}
r = requests.post(url, files=files)
print r.text, print r.json

ahh thanks @LukasGraf now i better understand what his original code is doing

import requests,json
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
my_json_data = json.load(open("request.json"))
req = requests.post(url,data=my_json_data)
print req.text
print 
print req.json # maybe? 

回答 3

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

它的python实现就像

import requests

headers = {
    'Content-Type': 'application/json',
}

params = (
    ('key', 'mykeyhere'),
)

data = open('request.json')
response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search', headers=headers, params=params, data=data)

#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere', headers=headers, data=data)

检查此链接,它将有助于将cURl命令转换为python,php和nodejs

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

its python implementation be like

import requests

headers = {
    'Content-Type': 'application/json',
}

params = (
    ('key', 'mykeyhere'),
)

data = open('request.json')
response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search', headers=headers, params=params, data=data)

#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere', headers=headers, data=data)

check this link, it will help convert cURl command to python,php and nodejs


回答 4

我的答案是WRT python 2.6.2。

import commands

status, output = commands.getstatusoutput("curl -H \"Content-Type:application/json\" -k -u (few other parameters required) -X GET https://example.org -s")

print output

对于未提供必需的参数,我深表歉意,因为这是机密信息。

My answer is WRT python 2.6.2.

import commands

status, output = commands.getstatusoutput("curl -H \"Content-Type:application/json\" -k -u (few other parameters required) -X GET https://example.org -s")

print output

I apologize for not providing the required parameters ‘coz it’s confidential.


回答 5

背景知识:我一直在寻找这个问题,因为我不得不做一些事情来检索内容,但是我所能得到的只是一个旧版本的python,它没有足够的SSL支持。如果您使用的是较旧的MacBook,那么您就会知道我在说什么。无论如何,都curl可以从Shell正常运行(我怀疑它已链接了现代SSL支持),因此有时您想要在不使用requests或的情况下执行此操作urllib2

您可以使用该subprocess模块执行curl并获取检索到的内容:

import subprocess

// 'response' contains a []byte with the retrieved content.
// use '-s' to keep curl quiet while it does its job, but
// it's useful to omit that while you're still writing code
// so you know if curl is working
response = subprocess.check_output(['curl', '-s', baseURL % page_num])

Python 3的subprocess模块还包含.run()许多有用的选项。我将其留给实际上正在运行python 3的人提供该答案。

Some background: I went looking for exactly this question because I had to do something to retrieve content, but all I had available was an old version of python with inadequate SSL support. If you’re on an older MacBook, you know what I’m talking about. In any case, curl runs fine from a shell (I suspect it has modern SSL support linked in) so sometimes you want to do this without using requests or urllib2.

You can use the subprocess module to execute curl and get at the retrieved content:

import subprocess

// 'response' contains a []byte with the retrieved content.
// use '-s' to keep curl quiet while it does its job, but
// it's useful to omit that while you're still writing code
// so you know if curl is working
response = subprocess.check_output(['curl', '-s', baseURL % page_num])

Python 3’s subprocess module also contains .run() with a number of useful options. I’ll leave it to someone who is actually running python 3 to provide that answer.


回答 6

这可以通过下面提到的伪代码方法来实现

Import os导入请求Data = os.execute(curl URL)R = Data.json()

This could be achieve with the below mentioned psuedo code approach

Import os import requests Data = os.execute(curl URL) R= Data.json()


Python中的CURL替代

问题:Python中的CURL替代

我在PHP中使用了一个cURL调用:

curl -i -H’接受:应用程序/ xml’-u登录名:密钥“ https://app.streamsend.com/emails

我需要一种在Python中执行相同操作的方法。在Python中是否可以使用cURL替代。我知道urllib,但我是Python菜鸟,也不知道如何使用它。

I have a cURL call that I use in PHP:

curl -i -H ‘Accept: application/xml’ -u login:key “https://app.streamsend.com/emails

I need a way to do the same thing in Python. Is there an alternative to cURL in Python. I know of urllib but I’m a Python noob and have no idea how to use it.


回答 0

import urllib2

manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
manager.add_password(None, 'https://app.streamsend.com/emails', 'login', 'key')
handler = urllib2.HTTPBasicAuthHandler(manager)

director = urllib2.OpenerDirector()
director.add_handler(handler)

req = urllib2.Request('https://app.streamsend.com/emails', headers = {'Accept' : 'application/xml'})

result = director.open(req)
# result.read() will contain the data
# result.info() will contain the HTTP headers

# To get say the content-length header
length = result.info()['Content-Length']

您的cURL调用使用urllib2代替。完全未经测试。

import urllib2

manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
manager.add_password(None, 'https://app.streamsend.com/emails', 'login', 'key')
handler = urllib2.HTTPBasicAuthHandler(manager)

director = urllib2.OpenerDirector()
director.add_handler(handler)

req = urllib2.Request('https://app.streamsend.com/emails', headers = {'Accept' : 'application/xml'})

result = director.open(req)
# result.read() will contain the data
# result.info() will contain the HTTP headers

# To get say the content-length header
length = result.info()['Content-Length']

Your cURL call using urllib2 instead. Completely untested.


回答 1

您可以使用“ 请求:人类的HTTP”用户指南中描述的HTTP请求。

You can use HTTP Requests that are described in the Requests: HTTP for Humans user guide.


回答 2

这是一个使用urllib2的简单示例,该示例针对GitHub的API进行了基本身份验证。

import urllib2

u='username'
p='userpass'
url='https://api.github.com/users/username'

# simple wrapper function to encode the username & pass
def encodeUserData(user, password):
    return "Basic " + (user + ":" + password).encode("base64").rstrip()

# create the request object and set some headers
req = urllib2.Request(url)
req.add_header('Accept', 'application/json')
req.add_header("Content-type", "application/x-www-form-urlencoded")
req.add_header('Authorization', encodeUserData(u, p))
# make the request and print the results
res = urllib2.urlopen(req)
print res.read()

此外,如果将其包装在脚本中并从终端运行,则可以将响应字符串传递到“ mjson.tool”以启用漂亮的打印。

>> basicAuth.py | python -mjson.tool

最后要注意的一点是,urllib2仅支持GET&POST请求。
如果您需要使用其他HTTP动词(例如DELETE,PUT等),则可能需要看一下PYCURL

Here’s a simple example using urllib2 that does a basic authentication against GitHub’s API.

import urllib2

u='username'
p='userpass'
url='https://api.github.com/users/username'

# simple wrapper function to encode the username & pass
def encodeUserData(user, password):
    return "Basic " + (user + ":" + password).encode("base64").rstrip()

# create the request object and set some headers
req = urllib2.Request(url)
req.add_header('Accept', 'application/json')
req.add_header("Content-type", "application/x-www-form-urlencoded")
req.add_header('Authorization', encodeUserData(u, p))
# make the request and print the results
res = urllib2.urlopen(req)
print res.read()

Furthermore if you wrap this in a script and run it from a terminal you can pipe the response string to ‘mjson.tool’ to enable pretty printing.

>> basicAuth.py | python -mjson.tool

One last thing to note, urllib2 only supports GET & POST requests.
If you need to use other HTTP verbs like DELETE, PUT, etc you’ll probably want to take a look at PYCURL


回答 3

如果您使用的是这样的命令来调用curl,则可以使用来在Python中执行相同的操作subprocess。例:

subprocess.call(['curl', '-i', '-H', '"Accept: application/xml"', '-u', 'login:key', '"https://app.streamsend.com/emails"'])

或者,如果您想将其作为像PHP一样具有更结构化的api,可以尝试PycURL

If you are using a command to just call curl like that, you can do the same thing in Python with subprocess. Example:

subprocess.call(['curl', '-i', '-H', '"Accept: application/xml"', '-u', 'login:key', '"https://app.streamsend.com/emails"'])

Or you could try PycURL if you want to have it as a more structured api like what PHP has.


回答 4

import requests

url = 'https://example.tld/'
auth = ('username', 'password')

r = requests.get(url, auth=auth)
print r.content

这是我所能获得的最简单的方法。

import requests

url = 'https://example.tld/'
auth = ('username', 'password')

r = requests.get(url, auth=auth)
print r.content

This is the simplest I’ve been able to get it.


回答 5

例如,如何使用urllib以及一些糖语法。我知道请求和其他库,但是urllib是python的标准库,不需要单独安装任何东西。

兼容Python 2/3。

import sys
if sys.version_info.major == 3:
  from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib.parse import urlencode
else:
  from urllib2 import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib import urlencode


def curl(url, params=None, auth=None, req_type="GET", data=None, headers=None):
  post_req = ["POST", "PUT"]
  get_req = ["GET", "DELETE"]

  if params is not None:
    url += "?" + urlencode(params)

  if req_type not in post_req + get_req:
    raise IOError("Wrong request type \"%s\" passed" % req_type)

  _headers = {}
  handler_chain = []

  if auth is not None:
    manager = HTTPPasswordMgrWithDefaultRealm()
    manager.add_password(None, url, auth["user"], auth["pass"])
    handler_chain.append(HTTPBasicAuthHandler(manager))

  if req_type in post_req and data is not None:
    _headers["Content-Length"] = len(data)

  if headers is not None:
    _headers.update(headers)

  director = build_opener(*handler_chain)

  if req_type in post_req:
    if sys.version_info.major == 3:
      _data = bytes(data, encoding='utf8')
    else:
      _data = bytes(data)

    req = Request(url, headers=_headers, data=_data)
  else:
    req = Request(url, headers=_headers)

  req.get_method = lambda: req_type
  result = director.open(req)

  return {
    "httpcode": result.code,
    "headers": result.info(),
    "content": result.read()
  }


"""
Usage example:
"""

Post data:
  curl("http://127.0.0.1/", req_type="POST", data='cascac')

Pass arguments (http://127.0.0.1/?q=show):
  curl("http://127.0.0.1/", params={'q': 'show'}, req_type="POST", data='cascac')

HTTP Authorization:
  curl("http://127.0.0.1/secure_data.txt", auth={"user": "username", "pass": "password"})

功能不完整,可能不理想,但显示了基本的表示形式和要使用的概念。可以根据口味添加或更改其他内容。

12/08更新

是GitHub实时更新源的链接。目前支持:

  • 授权

  • 兼容CRUD

  • 自动字符集检测

  • 自动编码(压缩)检测

Some example, how to use urllib for that things, with some sugar syntax. I know about requests and other libraries, but urllib is standard lib for python and doesn’t require anything to be installed separately.

Python 2/3 compatible.

import sys
if sys.version_info.major == 3:
  from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib.parse import urlencode
else:
  from urllib2 import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib import urlencode


def curl(url, params=None, auth=None, req_type="GET", data=None, headers=None):
  post_req = ["POST", "PUT"]
  get_req = ["GET", "DELETE"]

  if params is not None:
    url += "?" + urlencode(params)

  if req_type not in post_req + get_req:
    raise IOError("Wrong request type \"%s\" passed" % req_type)

  _headers = {}
  handler_chain = []

  if auth is not None:
    manager = HTTPPasswordMgrWithDefaultRealm()
    manager.add_password(None, url, auth["user"], auth["pass"])
    handler_chain.append(HTTPBasicAuthHandler(manager))

  if req_type in post_req and data is not None:
    _headers["Content-Length"] = len(data)

  if headers is not None:
    _headers.update(headers)

  director = build_opener(*handler_chain)

  if req_type in post_req:
    if sys.version_info.major == 3:
      _data = bytes(data, encoding='utf8')
    else:
      _data = bytes(data)

    req = Request(url, headers=_headers, data=_data)
  else:
    req = Request(url, headers=_headers)

  req.get_method = lambda: req_type
  result = director.open(req)

  return {
    "httpcode": result.code,
    "headers": result.info(),
    "content": result.read()
  }


"""
Usage example:
"""

Post data:
  curl("http://127.0.0.1/", req_type="POST", data='cascac')

Pass arguments (http://127.0.0.1/?q=show):
  curl("http://127.0.0.1/", params={'q': 'show'}, req_type="POST", data='cascac')

HTTP Authorization:
  curl("http://127.0.0.1/secure_data.txt", auth={"user": "username", "pass": "password"})

Function is not complete and possibly is not ideal, but shows a basic representation and concept to use. Additional things could be added or changed by taste.

12/08 update

Here is a GitHub link to live updated source. Currently supporting:

  • authorization

  • CRUD compatible

  • automatic charset detection

  • automatic encoding(compression) detection


回答 6

如果它正在从您要查找的命令行运行以上所有内容,那么我建议您使用HTTPie。这是一个奇妙的卷曲替代品,超级容易方便,以使用(和定制)。

这是来自GitHub的(简洁而准确的)描述;

HTTPie(发音为aych-tee-tee-pie)是命令行HTTP客户端。其目标是使CLI与Web服务的交互尽可能对人类友好。

它提供了一个简单的http命令,该命令允许使用简单自然的语法发送任意HTTP请求,并显示彩色输出。HTTPie可用于测试,调试和通常与HTTP服务器交互。


有关身份验证的文档应为您提供足够的指针来解决您的问题。当然,以上所有答案也是准确的,并且提供了完成同一任务的不同方法。


只是为了您不必离开Stack Overflow,这是它简而言之的功能。

Basic auth:

$ http -a username:password example.org
Digest auth:

$ http --auth-type=digest -a username:password example.org
With password prompt:

$ http -a username example.org

If it’s running all of the above from the command line that you’re looking for, then I’d recommend HTTPie. It is a fantastic cURL alternative and is super easy and convenient to use (and customize).

Here’s is its (succinct and precise) description from GitHub;

HTTPie (pronounced aych-tee-tee-pie) is a command line HTTP client. Its goal is to make CLI interaction with web services as human-friendly as possible.

It provides a simple http command that allows for sending arbitrary HTTP requests using a simple and natural syntax, and displays colorized output. HTTPie can be used for testing, debugging, and generally interacting with HTTP servers.


The documentation around authentication should give you enough pointers to solve your problem(s). Of course, all of the answers above are accurate as well, and provide different ways of accomplishing the same task.


Just so you do NOT have to move away from Stack Overflow, here’s what it offers in a nutshell.

Basic auth:

$ http -a username:password example.org
Digest auth:

$ http --auth-type=digest -a username:password example.org
With password prompt:

$ http -a username example.org

JSONDecodeError:预期值:第1行第1列(字符0)

问题:JSONDecodeError:预期值:第1行第1列(字符0)

Expecting value: line 1 column 1 (char 0)尝试解码JSON 时出现错误。

我用于API调用的URL在浏览器中可以正常工作,但是通过curl请求完成时会出现此错误。以下是我用于curl请求的代码。

错误发生在 return simplejson.loads(response_json)

    response_json = self.web_fetch(url)
    response_json = response_json.decode('utf-8')
    return json.loads(response_json)


def web_fetch(self, url):
        buffer = StringIO()
        curl = pycurl.Curl()
        curl.setopt(curl.URL, url)
        curl.setopt(curl.TIMEOUT, self.timeout)
        curl.setopt(curl.WRITEFUNCTION, buffer.write)
        curl.perform()
        curl.close()
        response = buffer.getvalue().strip()
        return response

完整回溯:

追溯:

File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/nab/Desktop/pricestore/pricemodels/views.py" in view_category
  620.     apicall=api.API().search_parts(category_id= str(categoryofpart.api_id), manufacturer = manufacturer, filter = filters, start=(catpage-1)*20, limit=20, sort_by='[["mpn","asc"]]')
File "/Users/nab/Desktop/pricestore/pricemodels/api.py" in search_parts
  176.         return simplejson.loads(response_json)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/__init__.py" in loads
  455.         return _default_decoder.decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in decode
  374.         obj, end = self.raw_decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in raw_decode
  393.         return self.scan_once(s, idx=_w(s, idx).end())

Exception Type: JSONDecodeError at /pricemodels/2/dir/
Exception Value: Expecting value: line 1 column 1 (char 0)

I am getting error Expecting value: line 1 column 1 (char 0) when trying to decode JSON.

The URL I use for the API call works fine in the browser, but gives this error when done through a curl request. The following is the code I use for the curl request.

The error happens at return simplejson.loads(response_json)

    response_json = self.web_fetch(url)
    response_json = response_json.decode('utf-8')
    return json.loads(response_json)


def web_fetch(self, url):
        buffer = StringIO()
        curl = pycurl.Curl()
        curl.setopt(curl.URL, url)
        curl.setopt(curl.TIMEOUT, self.timeout)
        curl.setopt(curl.WRITEFUNCTION, buffer.write)
        curl.perform()
        curl.close()
        response = buffer.getvalue().strip()
        return response

Full Traceback:

Traceback:

File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/nab/Desktop/pricestore/pricemodels/views.py" in view_category
  620.     apicall=api.API().search_parts(category_id= str(categoryofpart.api_id), manufacturer = manufacturer, filter = filters, start=(catpage-1)*20, limit=20, sort_by='[["mpn","asc"]]')
File "/Users/nab/Desktop/pricestore/pricemodels/api.py" in search_parts
  176.         return simplejson.loads(response_json)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/__init__.py" in loads
  455.         return _default_decoder.decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in decode
  374.         obj, end = self.raw_decode(s)
File "/Users/nab/Desktop/myenv2/lib/python2.7/site-packages/simplejson/decoder.py" in raw_decode
  393.         return self.scan_once(s, idx=_w(s, idx).end())

Exception Type: JSONDecodeError at /pricemodels/2/dir/
Exception Value: Expecting value: line 1 column 1 (char 0)

回答 0

总结评论中的对话:

  • 无需使用simplejson库,Python作为json模块包含了相同的库。

  • 无需解码UTF8对unicode的响应,simplejson/ json .loads()方法可以本地处理UTF8编码的数据。

  • pycurl有一个非常古老的API。除非您有特定的使用要求,否则会有更好的选择。

requests提供最友好的API,包括JSON支持。如果可以,将您的通话替换为:

import requests

return requests.get(url).json()

To summarize the conversation in the comments:

  • There is no need to use simplejson library, the same library is included with Python as the json module.

  • There is no need to decode a response from UTF8 to unicode, the simplejson / json .loads() method can handle UTF8 encoded data natively.

  • pycurl has a very archaic API. Unless you have a specific requirement for using it, there are better choices.

requests offers the most friendly API, including JSON support. If you can, replace your call with:

import requests

return requests.get(url).json()

回答 1

检查响应数据主体,是否存在实际数据并且数据转储的格式是否正确。

在大多数情况下,您的json.loadsJSONDecodeError: Expecting value: line 1 column 1 (char 0)错误是由于:

  • 非JSON引用
  • XML / HTML输出(即以<开头的字符串),或
  • 不兼容的字符编码

最终,错误告诉您字符串在第一位置已经不符合JSON。

这样,如果尽管乍一看具有看起来像JSON的数据主体,但解析仍然失败,请尝试替换数据主体的引号:

import sys, json
struct = {}
try:
  try: #try parsing to dict
    dataform = str(response_json).strip("'<>() ").replace('\'', '\"')
    struct = json.loads(dataform)
  except:
    print repr(resonse_json)
    print sys.exc_info()

注意:数据中的引号必须正确转义

Check the response data-body, whether actual data is present and a data-dump appears to be well-formatted.

In most cases your json.loadsJSONDecodeError: Expecting value: line 1 column 1 (char 0) error is due to :

  • non-JSON conforming quoting
  • XML/HTML output (that is, a string starting with <), or
  • incompatible character encoding

Ultimately the error tells you that at the very first position the string already doesn’t conform to JSON.

As such, if parsing fails despite having a data-body that looks JSON like at first glance, try replacing the quotes of the data-body:

import sys, json
struct = {}
try:
  try: #try parsing to dict
    dataform = str(response_json).strip("'<>() ").replace('\'', '\"')
    struct = json.loads(dataform)
  except:
    print repr(resonse_json)
    print sys.exc_info()

Note: Quotes within the data must be properly escaped


回答 2

当您有一个HTTP错误代码(例如404)并尝试将响应解析为JSON时,使用requestslib JSONDecodeError可能会发生!

您必须首先检查200(OK)或让它出现错误以避免这种情况。我希望它以较少的错误消息失败。

注意:就像注释中提到的Martijn Pieters一样,如果发生错误(取决于实现),服务器可以使用JSON进行响应,因此检查Content-Type标头更加可靠。

With the requests lib JSONDecodeError can happen when you have an http error code like 404 and try to parse the response as JSON !

You must first check for 200 (OK) or let it raise on error to avoid this case. I wish it failed with a less cryptic error message.

NOTE: as Martijn Pieters stated in the comments servers can respond with JSON in case of errors (it depends on the implementation), so checking the Content-Type header is more reliable.


回答 3

我认为值得一提的是,在您解析JSON文件本身的内容时-健全性检查对于确保您实际上在调用文件json.loads()内容(而不是该JSON 的文件路径)非常有用。:

json_file_path = "/path/to/example.json"

with open(json_file_path, 'r') as j:
     contents = json.loads(j.read())

我有些尴尬地承认有时会发生这种情况:

contents = json.loads(json_file_path)

I think it’s worth mentioning that in cases where you’re parsing the contents of a JSON file itself – sanity checks can be useful to ensure that you’re actually invoking json.loads() on the contents of the file, as opposed to the file path of that JSON:

json_file_path = "/path/to/example.json"

with open(json_file_path, 'r') as j:
     contents = json.loads(j.read())

I’m a little embarrassed to admit that this can happen sometimes:

contents = json.loads(json_file_path)

回答 4

检查文件的编码格式,并在读取文件时使用相应的编码格式。它将解决您的问题。

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)

Check encoding format of your file and use corresponding encoding format while reading file. It will solve your problem.

with open("AB.json", encoding='utf-8', errors='ignore') as json_data:
     data = json.load(json_data, strict=False)

回答 5

很多时候,这是因为您要解析的字符串为空:

>>> import json
>>> x = json.loads("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

您可以通过json_string事先检查是否为空来进行补救:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}

A lot of times, this will be because the string you’re trying to parse is blank:

>>> import json
>>> x = json.loads("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

You can remedy by checking whether json_string is empty beforehand:

import json

if json_string:
    x = json.loads(json_string)
else:
    // Your logic here
    x = {}

回答 6

即使调用了decode(),也可能嵌入了0。使用replace():

import json
struct = {}
try:
    response_json = response_json.decode('utf-8').replace('\0', '')
    struct = json.loads(response_json)
except:
    print('bad json: ', response_json)
return struct

There may be embedded 0’s, even after calling decode(). Use replace():

import json
struct = {}
try:
    response_json = response_json.decode('utf-8').replace('\0', '')
    struct = json.loads(response_json)
except:
    print('bad json: ', response_json)
return struct

回答 7

使用请求,我遇到了这个问题。感谢Christophe Roussy的解释。

为了调试,我使用了:

response = requests.get(url)
logger.info(type(response))

我从API返回了404响应。

I had exactly this issue using requests. Thanks to Christophe Roussy for his explanation.

To debug, I used:

response = requests.get(url)
logger.info(type(response))

I was getting a 404 response back from the API.


回答 8

我在请求(python库)时遇到了同样的问题。它恰好是accept-encoding标题。

它是这样设置的: 'accept-encoding': 'gzip, deflate, br'

我只是将其从请求中删除,并停止获取错误。

I was having the same problem with requests (the python library). It happened to be the accept-encoding header.

It was set this way: 'accept-encoding': 'gzip, deflate, br'

I simply removed it from the request and stopped getting the error.


回答 9

对我来说,它没有在请求中使用身份验证。

For me, it was not using authentication in the request.


回答 10

对我来说,这是服务器响应而不是200响应,并且响应不是json格式的。我最终在json解析之前执行了此操作:

# this is the https request for data in json format
response_json = requests.get() 

# only proceed if I have a 200 response which is saved in status_code
if (response_json.status_code == 200):  
     response = response_json.json() #converting from json to dictionary using json library

For me it was server responding with something other than 200 and the response was not json formatted. I ended up doing this before the json parse:

# this is the https request for data in json format
response_json = requests.get() 

# only proceed if I have a 200 response which is saved in status_code
if (response_json.status_code == 200):  
     response = response_json.json() #converting from json to dictionary using json library

回答 11

如果您是Windows用户,则Tweepy API可以在数据对象之间生成一个空行。由于这种情况,您会收到“ JSONDecodeError:预期值:第1行第1列(字符0)”错误。为避免此错误,您可以删除空行。

例如:

 def on_data(self, data):
        try:
            with open('sentiment.json', 'a', newline='\n') as f:
                f.write(data)
                return True
        except BaseException as e:
            print("Error on_data: %s" % str(e))
        return True

参考: Twitter流API从None给出JSONDecodeError(“ Expecting value”,s,err.value)

If you are a Windows user, Tweepy API can generate an empty line between data objects. Because of this situation, you can get “JSONDecodeError: Expecting value: line 1 column 1 (char 0)” error. To avoid this error, you can delete empty lines.

For example:

 def on_data(self, data):
        try:
            with open('sentiment.json', 'a', newline='\n') as f:
                f.write(data)
                return True
        except BaseException as e:
            print("Error on_data: %s" % str(e))
        return True

Reference: Twitter stream API gives JSONDecodeError(“Expecting value”, s, err.value) from None


回答 12

只需检查请求的状态码是否为200。例如:

if status != 200:
    print("An error has occured. [Status code", status, "]")
else:
    data = response.json() #Only convert to Json when status is OK.
    if not data["elements"]:
        print("Empty JSON")
    else:
        "You can extract data here"

Just check if the request has a status code 200. So for example:

if status != 200:
    print("An error has occured. [Status code", status, "]")
else:
    data = response.json() #Only convert to Json when status is OK.
    if not data["elements"]:
        print("Empty JSON")
    else:
        "You can extract data here"

回答 13

我在基于Python的Web API的响应中收到了这样的错误.text,但是它导致了我的到来,因此这可能会帮助遇到类似问题的其他人(使用requests.. 过滤响应并在搜索中请求问题非常困难)

使用json.dumps()要求 data ARG创建JSON的正确转义的字符串前发布解决了该问题对我来说

requests.post(url, data=json.dumps(data))

I received such an error in a Python-based web API’s response .text, but it led me here, so this may help others with a similar issue (it’s very difficult to filter response and request issues in a search when using requests..)

Using json.dumps() on the request data arg to create a correctly-escaped string of JSON before POSTing fixed the issue for me

requests.post(url, data=json.dumps(data))