记录一次IIS部署webform请求调用python服务的异常处理
Posted 丁小未
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录一次IIS部署webform请求调用python服务的异常处理相关的知识,希望对你有一定的参考价值。
需求
需要做一个获取视频网站的后台服务接口,输入一个房间号,获取对应的直播URL,然后给客户端展示直播。
分析
- 执行对应的python逻辑,输入房间号,返回直播URL
- 创建对应的webform一般处理程序服务,需要用到C#执行python
- 发布IIS,这里需要避免权限问题的坑
对应代码
Python
# 获取哔哩哔哩直播的真实流媒体地址,默认获取直播间提供的最高画质
# qn=150高清
# qn=250超清
# qn=400蓝光
# qn=10000原画
import requests
import argparse
parser = argparse.ArgumentParser(description='manual to this script')
parser.add_argument("--roomId", type=str, default="2171135", help='search roomId')
args = parser.parse_args()
class BiliBili:
def __init__(self, rid):
"""
有些地址无法在PotPlayer播放,建议换个播放器试试
Args:
rid:
"""
rid = rid
self.header =
'User-Agent': 'Mozilla/5.0 (iPod; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (Khtml, '
'like Gecko) Crios/87.0.4280.163 Mobile/15E148 Safari/604.1',
# 先获取直播状态和真实房间号
r_url = 'https://api.live.bilibili.com/room/v1/Room/room_init'
param =
'id': rid
with requests.Session() as self.s:
res = self.s.get(r_url, headers=self.header, params=param).json()
if res['msg'] == '直播间不存在':
raise Exception(f'bilibili rid res["msg"]')
live_status = res['data']['live_status']
if live_status != 1:
raise Exception(f'bilibili rid 未开播')
self.real_room_id = res['data']['room_id']
def get_real_url(self, current_qn: int = 10000) -> dict:
url = 'https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo'
param =
'room_id': self.real_room_id,
'protocol': '0,1',
'format': '0,1,2',
'codec': '0,1',
'qn': current_qn,
'platform': 'h5',
'ptype': 8,
res = self.s.get(url, headers=self.header, params=param).json()
stream_info = res['data']['playurl_info']['playurl']['stream']
qn_max = 0
for data in stream_info:
accept_qn = data['format'][0]['codec'][0]['accept_qn']
for qn in accept_qn:
qn_max = qn if qn > qn_max else qn_max
if qn_max != current_qn:
param['qn'] = qn_max
res = self.s.get(url, headers=self.header, params=param).json()
stream_info = res['data']['playurl_info']['playurl']['stream']
stream_urls =
# flv流无法播放,暂修改成获取hls格式的流,
for data in stream_info:
format_name = data['format'][0]['format_name']
if format_name == 'ts':
base_url = data['format'][-1]['codec'][0]['base_url']
url_info = data['format'][-1]['codec'][0]['url_info']
for i, info in enumerate(url_info):
host = info['host']
extra = info['extra']
stream_urls[f'线路i + 1'] = f'hostbase_urlextra'
break
return stream_urls
def get_real_url(rid):
try:
bilibili = BiliBili(rid)
return bilibili.get_real_url()
except Exception as e:
print('Exception:', e)
return False
if __name__ == '__main__':
#r = input('请输入bilibili直播房间号:\\n')
print(args.roomId)
print(get_real_url(args.roomId))
C#一般处理程序
using System;
using System.IO;
using System.Web;
namespace MonitorToolSystem
/// <summary>
/// GetBrocastLiveUrl 的摘要说明
/// </summary>
public class GetBrocastLiveUrl : IHttpHandler
public void ProcessRequest(HttpContext context)
context.Response.ContentType = "text/plain";
var roomId = context.Request["roomId"];
//服务器跟PC的python地址
string pyToolPath = @"C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python39\\python.exe"; //c:\\users\\d00605132\\appdata\\local\\programs\\python\\python39\\python.exe
//string pyToolPath = @"c:\\users\\d00605132\\appdata\\local\\programs\\python\\python39\\python.exe";
System.Diagnostics.Process p = new System.Diagnostics.Process();
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Pythons/bilibiliModify.py"); ;//(因为我没放debug下,所以直接写的绝对路径,替换掉上面的路径了)
string sArguments = path;
if (!string.IsNullOrEmpty(roomId))
sArguments = sArguments + $" --roomId=roomId";
p.StartInfo.FileName = pyToolPath;
p.StartInfo.UseShellExecute = true;
p.StartInfo.Arguments = sArguments;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = false;
p.Start();
while (!p.HasExited)
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
if (string.IsNullOrEmpty(output))
context.Response.Write($"error:沒有查询到房间数据");
else
context.Response.Write($"output");
public bool IsReusable
get
return false;
这里Python版本是3.9.6
IIS设置避坑
本地跑的好好的,但一旦发布IIS,就会碰到访问权限的问题,会报错System.ComponentModel.Win32Exception拒绝访问,首先IIS需要以管理员身份运行,其次在Web.config中配置管理员账户访问权限,在<system.web>中配置
<identity impersonate="true" userName="Administrator" password="xxx"/>
然后发现不报访问权限的错了,但是process没有返回值,这就很蛋疼,前面用户权限的问题坑了我一晚上,在公司处理到11点还没搞定失望而归,今天又在公司白天解决了访问权限的问题,但却没有正确得到返回值,又是解决问题,后来发现应用程序池需要设置标识为LocalSystem,非常重要,然后就能正确运行了
http://116.205.247.142:8080/GetBrocastLiveUrl.ashx?roomId=2171135
上图是房间号为2171135的直播间的直播线路地址,如果当前房间没有直播,就是返回一下值
结论
有以上经验,我就能做一个直播平台的聚合app了,只要知道各个平台的房间号,就能做一个根据直播类型分类的超大聚合直播app,是不是很开心呢!
以上是关于记录一次IIS部署webform请求调用python服务的异常处理的主要内容,如果未能解决你的问题,请参考以下文章
记录一次IIS部署webform请求调用python服务的异常处理