我正在尝试制作一个 Python 脚本,当我在终端上运行代码时(将 ngrok 可执行文件移动到 /usr/local/bin 后),它会报告 0.tcp.ngrok.io 上的端口已启动
ngrok tcp 22
我得到这样的输出
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status connecting
Version 2.2.4
Region United States (us)
Web Interface http://127.0.0.1:4041
Forwarding tcp://0.tcp.ngrok.io:13014 -> localhost:22
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
我的第一次尝试是将子进程标准输出记录到一个变量,但由于标准输出是循环的,stdout.read()永远不会结束,这就是代码
import subprocess
ngrok = subprocess.Popen(['ngrok','tcp','22'],stdout = subprocess.PIPE)
output_text = ngrok.stdout.read() # script stops here forever
[**code for getting domain:port from output_text**]
如何在不停止 ngrok 的情况下获得 stdout 的“快照”到变量?
是否有另一种方法可以做到这一点(下一次尝试将是本地主机上的网络爬虫,但如果能够了解其他命令(例如“top”)的知识就更好了)
提前致谢
当我使用
ngrok http
时,我遇到了同样的问题,并且所有替代方案都不起作用,导致死锁,我什至可以打印使用 ngrok 创建的子进程响应。因此,阅读 ngrok 文档 我注意到有一种方法可以通过请求获取 ngrok 公共 url。
添加以下代码:
localhost_url = "http://localhost:4041/api/tunnels" #Url with tunnel details
tunnel_url = requests.get(localhost_url).text #Get the tunnel information
j = json.loads(tunnel_url)
tunnel_url = j['Tunnels'][0]['PublicUrl'] #Do the parsing of the get
因此,tunnel_url 将返回您需要的内容。添加导入,完整代码将如下所示:
import subprocess
import requests
import json
ngrok = subprocess.Popen(['ngrok','tcp','22'],stdout = subprocess.PIPE)
localhost_url = "http://localhost:4041/api/tunnels" #Url with tunnel details
tunnel_url = requests.get(localhost_url).text #Get the tunnel information
j = json.loads(tunnel_url)
tunnel_url = j['Tunnels'][0]['PublicUrl'] #Do the parsing of the get
没有足够的声誉来发表评论,请随时更新或评论@Rodolfo很棒的答案,然后删除此
也许他们稍微改变了 api,这对我有用: (脚本旁边的 ngrok 可执行文件,在端口 5000 上提供 http 服务并选择 https 隧道 url)
import subprocess
import requests
import json
import time
if __name__ == '__main__':
ngrok = subprocess.Popen(['./ngrok','http','5000'],
stdout=subprocess.PIPE)
time.sleep(3) # to allow the ngrok to fetch the url from the server
localhost_url = "http://localhost:4040/api/tunnels" #Url with tunnel details
tunnel_url = requests.get(localhost_url).text #Get the tunnel information
j = json.loads(tunnel_url)
tunnel_url = j['tunnels'][1]['public_url'] #Do the parsing of the get
print(tunnel_url)
这对我有用:
def open_tunnel():
process = subprocess.Popen(f'/snap/bin/ngrok tcp {PORT} --log "stdout"', shell=True, stdout=PIPE, stderr=PIPE) # You can also use a list and put shell = False
while True:
output = process.stdout.readline()
if not output and process.poll() is not None:
break
elif b'url=' in output:
output = output.decode()
output = output[output.index('url=tcp://') + 10 : -1]
return output.split(':')
我使用
/snap/bin/ngrok
,因为我的pycharm无法识别路径,对此感到抱歉。您可以只说 ngrok
来替换它
.