使用python将Rest Api json结果转换为csv
Posted
技术标签:
【中文标题】使用python将Rest Api json结果转换为csv【英文标题】:RestApi json results into a csv using python 【发布时间】:2021-10-11 21:06:01 【问题描述】:我正在尝试将从RestApi
URL 返回的响应写入csv
文件,用于提供port number
(交互模式)和选定用户users_list.txt
(脚本模式)。我有下面的代码来完成这项工作。
import json
import csv
import urllib.request
import subprocess
portvalue = input("Please enter an Port Number:\n")
portvalue = int(portvalue)
print(f'You entered portvalue')
tooluser='admin'
toolpassword='password'
user = open('users-list.txt')
for line in user:
bash_com = 'curl --user tooluser:toolpassword http://198.98.99.12:46567/portvalue/protects/user \
| jq --arg a_port portvalue --arg a_userid user 'map(.+"userid":user+"port":portvalue)'' as url:
subprocess.Popen(bash_com)
output = subprocess.check_output(['bash','-c', bash_com])
print(line)
myfile.close()
# with urllib.request.urlopen("curl --user admin:password http://198.98.99.12:46567/port/protects/user | jq") as url:
data = json.loads(url.read().decode())
fname = "output.csv"
with open(fname, "w") as file:
csv_file = csv.writer(file,lineterminator='\n')
csv_file.writerow(["depotFile","host","isgroup","line","perm","user","port","userid"])
for item in data["raw_data"]:
csv_file.writerow([item['depotFile'],item['host'],item['isgroup'],item['line'],item['perm'],item['user'],item['port'],item['userid']])
使用 URL 获取单个用户的数据 - curl --user admin:password http://198.98.99.12:46567/2324/protects/sanchez.ricardo | jq
users_list.txt
由以下格式的用户组成。
sanchez.ricardo
varun.sharma
daniel.vel
json
输出格式之一如下,
[
"depotFile": "//LIB/Include/...",
"host": "*",
"isgroup": "",
"line": "19",
"perm": "open",
"user": "5G",
"port": "2324",
"userid": "sanchez.ricardo"
,
....
......
.........
]
预期的输出 csv 文件:-
Sno depotFile host isgroup line perm user port userid
1 //LIB/Include/... * 19 open 5G 2324 sanchez.ricardo
2 //LIB/... * 19 write 6G 2324 varun.sharma
3 //AND/RIO/... * 20 write AND 2324 daniel.vel
我无法处理上述代码中的RestApi URl
。请帮助我在 python 中实现这一点。提前感谢您的帮助。
【问题讨论】:
如果您仍然需要这方面的帮助,您能否添加一个包含两个用户的用户列表示例文件,以及您为获取两个用户的 csv 所点击的实际 url? @ Brian Z,是的,我仍在寻求帮助。我在问题中添加了userlist
文件和实际url
信息。请看看并帮助我。
【参考方案1】:
我喜欢使用请求来抓取东西,因为它现在很容易,比一开始有了很大的改进。它比 pyCurl 容易得多,因为我正在重构代码以使用它,因为我会随着时间的推移对代码进行改进。
这是一个非常酷的网站,可以将 curl 命令转换为请求代码:
https://curl.trillworks.com/
所以:
curl --user admin:password http://198.98.99.12:46567/2324/protects/sanchez.ricardo
是:
import requests
response = requests.get('http://198.98.99.12:46567/2324/protects/sanchez.ricardo', auth=('admin', 'password'))
现在在我看来,您的循环无法正常工作。它循环并将这些东西分配给bash,但在循环完成之前不做任何事情。可能你不小心取消了它。无论如何,这是一个应该工作的循环,使用另一个答案中建议的 f-strings 的建议。
我不完全确定你从 api 得到什么,似乎你需要为每个请求发出多个请求来获取 json,所以我是这样写的。我相信你需要调整一些东西,但这应该会让你更接近。
import requests
import json
import csv
user_csv = '''sanchez.ricardo
varun.sharma
daniel.vel'''
# I cannot tell where you get the ports from, so I will put a list here to show the code working
# and you can fill it differently, maybe from the csv?? not sure
ports = [2324, 2324, 2324]
users = user_csv.split('\n')
fname = "output.csv"
with open(fname, "w") as file:
csv_file = csv.writer(file,lineterminator='\n')
csv_file.writerow(["depotFile", "host", "isgroup", "line", "perm", "user", "port", "userid"])
for user, port in zip(users, ports):
print(f'from csv and other method here is the user and port: user, port')
url = f'http://198.98.99.12:46567/port/protects/user'
print(f'grab data from rest api: url')
# cannot tell if there is one user:password for the REST API, this code assumes so
response = requests.get(url, auth=('admin', 'password'))
# assuming response returns json like this:
# response = '''[
#
# "depotFile": "//LIB/Include/...",
# "host": "*",
# "isgroup": "",
# "line": "19",
# "perm": "open",
# "user": "5G",
# "port": "2324",
# "userid": "sanchez.ricardo"
# ]'''
data = json.loads(response)
for item in list(data):
csv_file.writerow(item.values())
【讨论】:
【参考方案2】:在这种情况下,f-string 可能就是您要查找的内容。考虑一下:-
user='sanchez.ricardo'
port=2324
url = f'http://198.98.99.12:46567/port/protects/user'
【讨论】:
'port' 是运行时输入变量,'user' 我需要从文本文件中传递。这种情况python怎么处理? 使用 input() 直接从用户获取信息(交互式)或传递命令行参数以获取端口值。打开文件并读取其内容以获取用户详细信息 您是否注意到当您尝试运行该代码时发生了什么?毫无疑问,urlopen 需要一个 URL 我只需要传递URL
而不是Curl along with URL
?
很遗憾,由于我无法访问主机站点,因此我无法为您编写和测试任何代码【参考方案3】:
你的第二个 sn-p 只覆盖了部分
curl --user $USERID:$PASSWORD http://198.98.99.12:46567/$PORT/protects/$u \
jq --arg a_port $PORT --arg a_userid .....
据我了解,您需要两种功能
-
来自用户输入 - 交互模式。
来自文件 - 脚本模式。
可以做很多事情,但我会做的是使用 Argeparse 并且可能有一个开关参数 -ulf|--users-list-file
来传递文件,或者根本没有交互模式的参数。
并通过环境变量传递端口,并使用os.environ 以及-p|--port
作为可选参数来读取它
一种快速而肮脏的方法是使用sys.argv 读取传递的参数并相应地编写您的条件。
【讨论】:
【参考方案4】:我一直在浏览您的代码,您可以简单地使用request 并使用pandas 将数据存储在CSV 中。这将使输出变得容易。
import json
import pandas as pd
json_string = ' "name":"John", "age":30, "car":"None" '
a_json = json.loads(json_string)
print(a_json)
dataframe = pd.DataFrame.from_dict(a_json)
【讨论】:
以上是关于使用python将Rest Api json结果转换为csv的主要内容,如果未能解决你的问题,请参考以下文章
ActiveCollab REST API 使用 Python 接收的嵌套 JSON 中的访问值 [已解决]