You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何借助Google可编程搜索实现带标签页的网页与图片搜索结果展示

如何借助Google可编程搜索实现带标签页的网页与图片搜索结果展示

看起来你已经迈出了很好的第一步,现在的核心问题是如何同时发起两种类型的搜索请求,并把结果分别渲染到对应的标签页里。其实不用纠结于“怎么加两个hndlr”,更清晰的思路是拆分回调函数,发起两个独立的API请求,分别处理网页和图片的结果,再把它们渲染到各自的标签容器中。下面是具体的实现方案:


1. 先修正DOM中的重复ID问题

你原来的代码里有两个id="resultmeta",这会导致JS无法正确区分它们,所以先把它们改成唯一ID:

  • 网页标签页的元信息容器改成id="web-resultmeta"
  • 图片标签页的改成id="image-resultmeta"

2. 拆分回调函数,各司其职

原来的hndlr既要处理网页又要处理图片,逻辑太混乱。我们拆成两个专属函数:

  • handleWebResults:专门处理网页搜索响应,渲染到「Search Results」标签页
  • handleImageResults:专门处理图片搜索响应,渲染到「Image Results」标签页

每个函数只负责自己的容器,不会清空或修改对方的内容,避免冲突。

3. 发起两个独立的API请求

分别构造网页和图片搜索的API URL,创建两个<script>标签插入文档,各自调用对应的回调函数即可。


修改后的完整代码

HTML部分(修正ID后的结构)

<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
</head>

<body>
   <form action="searchresults.html" id="cse-search-box">
        <div>
            <input class="" name="q" type="text"> 
            <input class="" type="submit">
        </div>
    </form>
    
    <ul class="nav nav-tabs" id="mytabs" role="tablist">
      <li class="nav-item" role="presentation">
        <a class="nav-link active" id="tab-0" data-bs-toggle="tab" href="#tabpanel-0" role="tab" aria-controls="tabpanel-0" aria-selected="true">Search Results</a>
      </li>
      <li class="nav-item" role="presentation">
        <a class="nav-link" id="tab-1" data-bs-toggle="tab" href="#tabpanel-1" role="tab" aria-controls="tabpanel-1" aria-selected="false">Image Results</a>
      </li>
    </ul>
    
    <div class="tab-content pt-5" id="tab-content">
    <div class="tab-pane active" id="tabpanel-0" role="tabpanel" aria-labelledby="tab-0">
    <div class="gsc-result-info" id="web-resultmeta"></div>
         <div id="searchresults"></div>
    </div>

    <div class="tab-pane" id="tabpanel-1" role="tabpanel" aria-labelledby="tab-1">
    <div class="gsc-result-info" id="image-resultmeta"></div>
         <div id="images"></div></div>
    </div>

<script>
// JavaScript 代码放在这里
</script>
</body>
</html>

JavaScript部分(拆分回调+双请求)

// 处理网页搜索结果
function handleWebResults(response) {
    // 更新网页结果的元信息
    document.getElementById("web-resultmeta").innerHTML = 
        "About " + response.searchInformation.formattedTotalResults + " results (" + response.searchInformation.formattedSearchTime + " seconds)";

    // 清空网页结果容器
    const webResultsContainer = document.getElementById("searchresults");
    webResultsContainer.innerHTML = "";

    // 渲染网页搜索结果
    for (var i = 0; i < response.items.length; i++) {
        var item = response.items[i];
        var content = "";

        // 网页结果标题链接
        content += "<a class='gs-title' href='" + item.link + "'>" + item.htmlTitle + "</a><br />";
        
        // 网页结果缩略图(判断是否存在,避免报错)
        if (item.pagemap?.cse_thumbnail) {
            content += "<a href='" + item.link + "'><img src='" + item.pagemap.cse_thumbnail[0].src + "'></a>";
        }
        
        // 网页结果摘要
        if (item.htmlSnippet) {
            content += "<p>" + item.htmlSnippet + "</p>";
        }

        // 将结果添加到容器
        const resultDiv = document.createElement("div");
        resultDiv.innerHTML = content;
        webResultsContainer.appendChild(resultDiv);
    }

    // 渲染网页结果分页
    var totalPages = Math.ceil(response.searchInformation.totalResults / 10);
    var currentPage = Math.floor(start / 10 + 1);
    var pageControls = "<div class='gsc-results'><div class='gsc-cursor-box gs-bidi-start-align' dir='ltr'><div class='gsc-cursor'>";
    for (var x = 1; x <= totalPages && x <=10; x++) {
        pageControls += "<div class='gsc-cursor-page";
        if (x === currentPage)
            pageControls += " gsc-cursor-current-page";
        var pageLinkStart = x * 10 - 9;
        pageControls += "'><a href='test.html?start="+pageLinkStart+"&q="+query+"'>"+x+"</a></div>";
    }
    pageControls += "</div></div></div>";
    webResultsContainer.innerHTML += pageControls;
}

// 处理图片搜索结果
function handleImageResults(response) {
    // 更新图片结果的元信息
    document.getElementById("image-resultmeta").innerHTML = 
        "About " + response.searchInformation.formattedTotalResults + " results (" + response.searchInformation.formattedSearchTime + " seconds)";

    // 清空图片结果容器
    const imageResultsContainer = document.getElementById("images");
    imageResultsContainer.innerHTML = "";

    // 渲染图片搜索结果
    for (var i = 0; i < response.items.length; i++) {
        var item = response.items[i];
        var content = "";

        // 图片链接与原图展示
        content += "<a href='" + item.link + "' target='_blank'><img src='" + item.link + "' alt='" + item.title + "' style='max-width:200px; margin:10px;'></a>";
        
        // 图片标题
        content += "<p>" + item.title + "</p>";

        // 将结果添加到容器
        const resultDiv = document.createElement("div");
        resultDiv.innerHTML = content;
        imageResultsContainer.appendChild(resultDiv);
    }

    // 渲染图片结果分页(确保分页时仍为图片搜索)
    var totalPages = Math.ceil(response.searchInformation.totalResults / 10);
    var currentPage = Math.floor(start / 10 + 1);
    var pageControls = "<div class='gsc-results'><div class='gsc-cursor-box gs-bidi-start-align' dir='ltr'><div class='gsc-cursor'>";
    for (var x = 1; x <= totalPages && x <=10; x++) {
        pageControls += "<div class='gsc-cursor-page";
        if (x === currentPage)
            pageControls += " gsc-cursor-current-page";
        var pageLinkStart = x * 10 - 9;
        pageControls += "'><a href='test.html?start="+pageLinkStart+"&q="+query+"&searchType=image'>"+x+"</a></div>";
    }
    pageControls += "</div></div></div>";
    imageResultsContainer.innerHTML += pageControls;
}

// 获取查询参数(处理特殊字符与截断)
var query = document.URL.substr(document.URL.indexOf("q=") + 2);
if (query.includes("&")) {
    query = query.split("&")[0];
}
var start = document.URL.substr(document.URL.indexOf("start=") + 6, 2);
if (start === "1&" || document.URL.indexOf("start=") === -1)
    start = 1;

// 发起网页搜索请求
var webSearchScript = document.createElement("script");
webSearchScript.type = "application/javascript";
webSearchScript.src = "https://www.googleapis.com/customsearch/v1?key=YOUR_API_KEY&cx=YOUR_CX&start="+start+"&q=" + encodeURIComponent(query) + "&callback=handleWebResults";
document.body.appendChild(webSearchScript);

// 发起图片搜索请求
var imageSearchScript = document.createElement("script");
imageSearchScript.type = "application/javascript";
imageSearchScript.src = "https://www.googleapis.com/customsearch/v1?key=YOUR_API_KEY&cx=YOUR_CX&start="+start+"&q=" + encodeURIComponent(query) + "&searchType=image&callback=handleImageResults";
document.body.appendChild(imageSearchScript);

额外注意事项

  1. 确保你的API Key和CX值正确,且已在Google Cloud控制台启用图片搜索权限;
  2. 注意API调用限制:免费版Google Custom Search API有每日调用限额,避免超出;
  3. 可以进一步优化样式(比如把图片结果改成网格布局),让界面更接近Google托管版的体验。

备注:内容来源于stack exchange,提问作者user5853892

火山引擎 最新活动