跳转至

SearchApi

modules.search.SearchApi

SearchApi(client: Client)

Bases: ApiModule

搜索相关 API.

Source code in qqmusic_api/modules/_base.py
def __init__(self, client: "Client") -> None:
    self._client = client
    self._session = client._session

get_hotkey

get_hotkey() -> CgiRequest[HotkeyResponse]

获取热搜词列表.

RETURNS DESCRIPTION
CgiRequest[HotkeyResponse]

CgiRequest[HotkeyResponse]: 热搜词列表请求描述符.

Source code in qqmusic_api/modules/search.py
def get_hotkey(self) -> CgiRequest[HotkeyResponse]:
    """获取热搜词列表.

    Returns:
        CgiRequest[HotkeyResponse]: 热搜词列表请求描述符.
    """
    return self._build_cgi(
        "music.musicsearch.HotkeyService",
        "GetHotkeyForQQMusicMobile",
        {"search_id": get_searchID()},
        response_model=HotkeyResponse,
    )

complete

complete(keyword: str) -> CgiRequest[CompleteResponse]

搜索词补全建议.

PARAMETER DESCRIPTION
keyword

关键词.

TYPE: str

RETURNS DESCRIPTION
CgiRequest[CompleteResponse]

CgiRequest[CompleteResponse]: 补全建议请求描述符.

Source code in qqmusic_api/modules/search.py
def complete(self, keyword: str) -> CgiRequest[CompleteResponse]:
    """搜索词补全建议.

    Args:
        keyword: 关键词.

    Returns:
        CgiRequest[CompleteResponse]: 补全建议请求描述符.
    """
    return self._build_cgi(
        "music.smartboxCgi.SmartBoxCgi",
        "GetSmartBoxResult",
        {
            "search_id": get_searchID(),
            "query": keyword,
            "num_per_page": 0,
            "page_idx": 0,
        },
        response_model=CompleteResponse,
    )
quick_search(
    keyword: str,
) -> HttpRequest[QuickSearchResponse]

快速搜索.

PARAMETER DESCRIPTION
keyword

关键词.

TYPE: str

RETURNS DESCRIPTION
HttpRequest[QuickSearchResponse]

HttpRequest[QuickSearchResponse]: 快速搜索结果请求描述符.

Source code in qqmusic_api/modules/search.py
def quick_search(self, keyword: str) -> HttpRequest[QuickSearchResponse]:
    """快速搜索.

    Args:
        keyword: 关键词.

    Returns:
        HttpRequest[QuickSearchResponse]: 快速搜索结果请求描述符.
    """
    return self._build_http(
        "GET",
        "https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg",
        params={"key": keyword},
        response_model=QuickSearchResponse,
    )
general_search(
    keyword: str,
    page: int = 1,
    num: int = 15,
    searchid: str | None = None,
    page_start: dict[str, Any] | None = None,
    *,
    highlight: bool = True,
)

综合搜索.

PARAMETER DESCRIPTION
keyword

关键词.

TYPE: str

page

页码.

TYPE: int DEFAULT: 1

num

每页返回数量.

TYPE: int DEFAULT: 15

searchid

搜索会话 ID.

TYPE: str | None DEFAULT: None

page_start

上一页分页游标对象.

TYPE: dict[str, Any] | None DEFAULT: None

highlight

是否高亮关键词.

TYPE: bool DEFAULT: True

Source code in qqmusic_api/modules/search.py
def general_search(
    self,
    keyword: str,
    page: int = 1,
    num: int = 15,
    searchid: str | None = None,
    page_start: dict[str, Any] | None = None,
    *,
    highlight: bool = True,
):
    """综合搜索.

    Args:
        keyword: 关键词.
        page: 页码.
        num: 每页返回数量.
        searchid: 搜索会话 ID.
        page_start: 上一页分页游标对象.
        highlight: 是否高亮关键词.
    """
    param: dict[str, Any] = {
        "searchid": searchid or get_searchID(),
        "search_type": 100,
        "page_num": num,
        "query": keyword,
        "page_id": page,
        "highlight": highlight,
        "grp": True,
    }
    if page_start is not None:
        param["page_start"] = page_start

    return self._build_cgi(
        "music.adaptor.SearchAdaptor",
        "do_search_v2",
        param,
        response_model=GeneralSearchResponse,
        pager_strategy=MultiFieldContinuationStrategy[GeneralSearchResponse](
            lambda params, response: {
                **params,
                "searchid": response.searchid,
                "page_id": response.nextpage,
                "page_start": response.nextpage_start,
            },
            has_more_extractor=lambda response: response.nextpage != -1,
            context_name="general_search",
        ),
    )

search_by_type

search_by_type(
    keyword: str,
    search_type: Literal[
        SONG, 0, LYRIC, 7, AUDIO, 18, RINGTONE, 10
    ] = SONG,
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
) -> ItemPaginatedCgiRequest[
    SearchByTypeResponse, SongSearch
]
search_by_type(
    keyword: str,
    search_type: Literal[SINGER, 1],
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
) -> ItemPaginatedCgiRequest[
    SearchByTypeResponse, SingerSearch
]
search_by_type(
    keyword: str,
    search_type: Literal[ALBUM, 2, AUDIO_ALBUM, 15],
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
) -> ItemPaginatedCgiRequest[
    SearchByTypeResponse, AlbumSearch
]
search_by_type(
    keyword: str,
    search_type: Literal[SONGLIST, 3],
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
) -> ItemPaginatedCgiRequest[
    SearchByTypeResponse, SongListSearch
]
search_by_type(
    keyword: str,
    search_type: Literal[MV, 4],
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
) -> ItemPaginatedCgiRequest[
    SearchByTypeResponse, MvSearch
]
search_by_type(
    keyword: str,
    search_type: Literal[USER, 8],
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
) -> ItemPaginatedCgiRequest[
    SearchByTypeResponse, dict[str, Any]
]
search_by_type(
    keyword: str,
    search_type: int | SearchType = SONG,
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
)

类型搜索.

固定使用 Android 平台.

PARAMETER DESCRIPTION
keyword

关键词.

TYPE: str

search_type

搜索类型.

TYPE: int | SearchType DEFAULT: SONG

num

返回结果数量.

TYPE: int DEFAULT: 10

page

页码.

TYPE: int DEFAULT: 1

selectors

搜索筛选器列表.

TYPE: list[SearchSelector] | None DEFAULT: None

searchid

搜索会话 ID.

TYPE: str | None DEFAULT: None

highlight

是否高亮关键词.

TYPE: bool DEFAULT: True

Source code in qqmusic_api/modules/search.py
def search_by_type(
    self,
    keyword: str,
    search_type: int | SearchType = SearchType.SONG,
    num: int = 10,
    page: int = 1,
    selectors: list[SearchSelector] | None = None,
    searchid: str | None = None,
    *,
    highlight: bool = True,
):
    """类型搜索.

    固定使用 Android 平台.

    Args:
        keyword: 关键词.
        search_type: 搜索类型.
        num: 返回结果数量.
        page: 页码.
        selectors: 搜索筛选器列表.
        searchid: 搜索会话 ID.
        highlight: 是否高亮关键词.
    """
    normalized_search_type = int(SearchType(search_type))

    def _extract_items(
        r: SearchByTypeResponse,
    ) -> (
        list[SongSearch]
        | list[SingerSearch]
        | list[AlbumSearch]
        | list[SongListSearch]
        | list[MvSearch]
        | list[dict[str, Any]]
    ):
        return r.song or r.singer or r.album or r.songlist or r.mv or r.user or r.audio_alum or []

    return self._build_cgi(
        "music.search.SearchCgiService",
        "DoSearchForQQMusicMobile",
        {
            "searchid": searchid or get_searchID(),
            "query": keyword,
            "search_type": normalized_search_type,
            "num_per_page": num,
            "page_num": page,
            "highlight": highlight,
            "grp": True,
            "selectors": {str(selector.type): str(selector.id) for selector in selectors} if selectors else {},
            "vec_selectors": [
                {"type": selector.type, "name": selector.name, "id": selector.id} for selector in selectors
            ]
            if selectors
            else [],
        },
        platform=Platform.ANDROID,
        response_model=SearchByTypeResponse,
        pager_strategy=PageStrategy[SearchByTypeResponse](
            page_key="page_num",
            page_size=num,
            start_page=page,
            has_more_extractor=lambda r: r.nextpage != -1,
            total_extractor=lambda r: r.total_num,
        ),
    ).with_extractor(_extract_items)