urllib 和 aiohttp 之间的不同结果
Different result between urllib and aiohttp
所以基本上我正在尝试从在线广播直接获取当前播放的曲目 link(示例 -
http://air.radiorecord.ru:8101/rr_320).
首先我在网上找到了一些东西,用urllib写的,我的应用程序是异步的所以我需要使用aiohttp。使用 urllib 它工作得很好,而 aiohttp 有时找不到任何东西。请帮助:(
之前:
def get_now(self, session):
request = urllib.Request(self.data.get('url'),headers={'Icy-MetaData': 1} ) # request metadata
response = urllib.urlopen(request)
metadata = response.headers
metaint = int(response.headers['icy-metaint'])
for _ in range(10): # title may be empty initially, try several times
response.read(metaint) # skip to metadata
metadata_length = struct.unpack('B', response.read(1))[0] * 16 # length byte
metadata = response.read(metadata_length).rstrip(b'[=10=]')
# extract title from the metadata
m = re.search(br"StreamTitle='([^']*)';", metadata)
if m:
title = m.group(1)
if title:
break
else:
return "No title found"
return title.decode('utf8', errors='replace')
except:
return "No title found"
之后:
async def get_now(self, session):
async with session.get(self.stream_url, headers={'Icy-MetaData': "1"}) as resp:
content = resp.content
metadata = resp.headers
metaint = int(metadata['icy-metaint'])
for _ in range(30):
await content.read(metaint)
metadata_length = struct.unpack('B', await content.read(1))[0] * 16 # length byte
metadata = (await content.read(metadata_length)).rstrip(b'[=11=]')
m = re.search(br"StreamTitle='([^']*)';", metadata)
if m:
title = m.group(1)
if title:
return title.decode('utf8', errors='replace')
else:
return "No title found"
return "Nothing found"
下面的代码片段始终能够检测到当前曲目(大约 400 毫秒),但它不是只处理部分块,而是在读取时检查整个块:
import aiohttp
import asyncio
import re
async def get_now(stream_url, session):
headers={"Icy-MetaData": "1"}
async with session.get(stream_url, headers=headers) as resp:
for _ in range(10):
data = await resp.content.read(8192)
m = re.search(br"StreamTitle='([^']*)';", data.rstrip(b"[=10=]"))
if m:
title = m.group(1)
if title:
return title.decode("utf8", errors="replace")
else:
return "No title found"
return "Nothing found"
async def get_track():
session = aiohttp.ClientSession()
stream_url = "http://air.radiorecord.ru:8101/rr_320"
result = await get_now(stream_url, session)
print(f"result: {result}")
await session.close()
asyncio.run(get_track())
我电脑上的结果(CPU 在相当老的 CPU 上使用率非常低:i7-3517U):
[ionut@ionut-pc ~]$ time python test.py
result: Record Club - Nejtrino & Baur
real 0m0.401s
user 0m0.198s
sys 0m0.031s
所以基本上我正在尝试从在线广播直接获取当前播放的曲目 link(示例 - http://air.radiorecord.ru:8101/rr_320).
首先我在网上找到了一些东西,用urllib写的,我的应用程序是异步的所以我需要使用aiohttp。使用 urllib 它工作得很好,而 aiohttp 有时找不到任何东西。请帮助:(
之前:
def get_now(self, session):
request = urllib.Request(self.data.get('url'),headers={'Icy-MetaData': 1} ) # request metadata
response = urllib.urlopen(request)
metadata = response.headers
metaint = int(response.headers['icy-metaint'])
for _ in range(10): # title may be empty initially, try several times
response.read(metaint) # skip to metadata
metadata_length = struct.unpack('B', response.read(1))[0] * 16 # length byte
metadata = response.read(metadata_length).rstrip(b'[=10=]')
# extract title from the metadata
m = re.search(br"StreamTitle='([^']*)';", metadata)
if m:
title = m.group(1)
if title:
break
else:
return "No title found"
return title.decode('utf8', errors='replace')
except:
return "No title found"
之后:
async def get_now(self, session):
async with session.get(self.stream_url, headers={'Icy-MetaData': "1"}) as resp:
content = resp.content
metadata = resp.headers
metaint = int(metadata['icy-metaint'])
for _ in range(30):
await content.read(metaint)
metadata_length = struct.unpack('B', await content.read(1))[0] * 16 # length byte
metadata = (await content.read(metadata_length)).rstrip(b'[=11=]')
m = re.search(br"StreamTitle='([^']*)';", metadata)
if m:
title = m.group(1)
if title:
return title.decode('utf8', errors='replace')
else:
return "No title found"
return "Nothing found"
下面的代码片段始终能够检测到当前曲目(大约 400 毫秒),但它不是只处理部分块,而是在读取时检查整个块:
import aiohttp
import asyncio
import re
async def get_now(stream_url, session):
headers={"Icy-MetaData": "1"}
async with session.get(stream_url, headers=headers) as resp:
for _ in range(10):
data = await resp.content.read(8192)
m = re.search(br"StreamTitle='([^']*)';", data.rstrip(b"[=10=]"))
if m:
title = m.group(1)
if title:
return title.decode("utf8", errors="replace")
else:
return "No title found"
return "Nothing found"
async def get_track():
session = aiohttp.ClientSession()
stream_url = "http://air.radiorecord.ru:8101/rr_320"
result = await get_now(stream_url, session)
print(f"result: {result}")
await session.close()
asyncio.run(get_track())
我电脑上的结果(CPU 在相当老的 CPU 上使用率非常低:i7-3517U):
[ionut@ionut-pc ~]$ time python test.py
result: Record Club - Nejtrino & Baur
real 0m0.401s
user 0m0.198s
sys 0m0.031s