Python urllib和aiohttp之间的不同结果

Python urllib和aiohttp之间的不同结果,python,urllib,aiohttp,Python,Urllib,Aiohttp,所以基本上,我试图从在线广播直接链接(例如)获取当前播放的曲目- ) 首先,我在互联网上发现了一些东西,是用urllib编写的,我的应用程序是异步的,所以我需要使用aiohttp。使用urllib,它工作得非常完美,而aiohttp有时就是找不到任何东西。请帮忙:( 之前: def get_now(self, session): request = urllib.Request(self.data.get('url'),headers={'Icy-MetaData': 1} ) # re

所以基本上,我试图从在线广播直接链接(例如)获取当前播放的曲目- )

首先,我在互联网上发现了一些东西,是用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'\0')

        # 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'\0')

            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"

下面的代码段始终能够检测到当前曲目(大约400ms),但它不是只处理部分块,而是在读取时检查整个块:

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"\0"))
            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
结果:唱片俱乐部-内杰特里诺和鲍尔
实0.401s
用户0.198s
系统0m0.031s

那么这怎么办呢?你只需要修改上面的最小工作示例来使用你的类(基本上是从
self
获取
stream\u url
而不是一个参数)。
get\u track
函数只是用来测试
get\u now
函数的。哦,弗里克,耶。谢谢兄弟:D