如何在Google App引擎(python)上获取流式网址的响应

时间:2015-06-12 15:29:20

标签: python google-app-engine urllib2 urlfetch

我正在尝试验证在线广播网址是否正在传送音乐以及网址是否被重定向(如果由于某种原因请求网址错误或未激活,则会发生这种情况)。我在这里找到了一些建议Fetching url in python with google app engine。但是,对于提供Content-Type:audio / mpeg的URL,它似乎不起作用。

在我的本地机器上使用python 2.7.6 urllib2.urlopen一切都很好:

try:
    print "begin urlopen"
    url = urllib2.urlopen("http://streaming.radionomy.com/jamaican-roots-radio")
    print "end urlopen"

except Exception, e:
    print e

给出

  

开始urlopen

     

end urlopen

我可以从返回的对象(这是一个socket._fileobject)中读取N个字节,并使用方法 geturl()来获取流来自的实际URL(如果有的话)没有重定向请求URL和检索到的资源URL是相同的)

使用dev_appserver.py for google appengine(我尚未部署)出现问题。电话永远不会回来:

  

开始urlopen

     

警告2015-06-12 14:31:43,499 urlfetch_stub.py:504]从URLFetch请求中删除禁止的标头:['Host']

永远不会打印

和“end urlopen”。

我理解警告错误,因此我将(如上面的链接中所示)切换到urlfetch:

try:
    print "begin fetch"
    url = urlfetch.fetch("http://streaming.radionomy.com/jamaican-roots-radio")
    print "end fetch"

except Exception, e:
    print e

给出

  

开始

警告消失了,但是再次呼叫没有返回。

对于普通网页网址,一切都符合预期。我想这个问题是从未完成的响应对象。也使用

urlfetch.set_default_fetch_deadline(5)

不会改变这种情况,可能是因为数据是从服务器连续流式传输的(因此没有调用超时??)。 我也尝试过低级 httplib.HTTPConnection ,但在发出请求后, getresponse()函数永远不会返回。

就我的目的而言,响应标题就足够了。但是在服务器上(不受我的控制),HEAD方法没有实现(尽管列在Access-Control-Allow-Methods中,因为它可以从浏览器中看到)

curl -X HEAD -i http://streaming.radionomy.com/jamaican-roots-radio
  

HTTP / 1.0 501未实现

我没有在stackoverflow上找到任何关于流URL的情况,除了这个问题 How to call Twitter's Streaming/Filter Feed with urllib2/httplib?。不幸的是,建议的回复对我来说并不是很有帮助(“使用Twitter的'标准'API')。

我有什么想法可以解决这个问题吗?

更新

在google appengine上(不是上面的dev_appserver.py)问题类似:

  • 截止日期为5秒
  

等待来自URL的HTTP响应时超过了截止日期...

  • 截止日期为60秒
  

追踪(最近一次呼叫最后一次):

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py”,第267行,处理结果=处理程序(dict(self._environ),self ._StartResponse)

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py”,第1505行,致电       rv = self.router.dispatch(请求,响应)

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py”,第1253行,在default_dispatcher中       return route.handler_adapter(request,response)

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py”,第1077行,致电       return handler.dispatch()

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.3/webapp2.py”,第545行,发送       return方法(* args,** kwargs)

     

文件“/base/data/home/apps/s~radiosnoozers/3.384985169499124712/controllers/checkurl.py”,第80行,获取       打印e

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/request_environment.py”,第94行,写入       self._request.errors.write(数据)

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/logservice/logservice.py”,第287行,写入       self._write(线)

     

文件“/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/logservice/logservice.py”,第307行,在_write中       if self._request!= logsutil.RequestID():

     

DeadlineExceededError

通过使用allow_truncated = True,可以使用超时并且没有区别。在任何情况下,都无法访问响应...

我真的不知道发生了什么,但感谢给定的建议。

2 个答案:

答案 0 :(得分:0)

如果该URL是通过HTTP的流端点,则可能使用http范围请求完成。这意味着如果你只想获取流的某个字节范围(比如前几个字节),你需要告诉urlfetch这样做。您可以通过指定request headers for urlfetch并指定字节范围来执行此操作(例如headers = {'Range':'bytes = 0-299'})

答案 1 :(得分:0)

UrlFetch用于从URL获取有限资源,并且通常不能很好地使用流。它正在等待终止请求。我相信端点在一般情况下对Range个请求不能很好地发挥作用。当我的浏览器访问该流时,请查看标题(顺便说一下,很棒的流):

GET http://streaming.radionomy.com/jamaican-roots-radio HTTP/1.1
Host: streaming.radionomy.com
Proxy-Connection: keep-alive
Accept-Encoding: identity;q=1, *;q=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
Accept: */*
Referer: http://streaming.radionomy.com/jamaican-roots-radio
Accept-Language: en-US,en;q=0.8
Cookie: gsScrollPos=
Range: bytes=0-

现在看一下回复:

HTTP/1.1 200 OK
Accept-Ranges: none
icy-br: 128
ice-audio-info: bitrate=128;samplerate=44100;channels=2
icy-br: 128
icy-description: Radio Online producida en Colombia.  Al aire: Ska Reggae Rocksteady jamaiquino las 24 horas los 7 días a la semana. http://www.jamaicanroots.com.co/
icy-genre: Jamaican
icy-name: JamaicanRootsRadio
icy-pub: 1
icy-url: http://www.jamaicanroots.com.co
Server: Icecast 2.3.3-kh8
Cache-Control: no-cache, no-store
Pragma: no-cache
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type
Access-Control-Allow-Methods: GET, OPTIONS, HEAD
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Transfer-Encoding: chunked
Content-Type: audio/mpeg
Date: Wed, 17 Jun 2015 19:35:42 GMT
Via: **[my proxy here]**
Connection: keep-alive
Proxy-Connection: keep-alive

事实上,正如我上面提到的,我认为流本身并不适合HTTP。如果您尝试通过CURL运行等效请求并指定Range: bytes=0-100,您将注意到Range请求标头未被遵守,并且它将永远流。

因此,您似乎需要使用Managed VMCompute Engine实例来手动打开和关闭连接。