Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)
Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)
体验 冒号搜索
1. 获取谷歌搜索api
2. 后台调用
程序入口 main.go
// goSearch project main.go
package main
import (
"fmt"
"net/http"
)
func main() {
Api()
ReadApi("./api.txt")
go TimeTo()
http.HandleFunc("/", Home)
http.HandleFunc("/search", Search)
http.Handle("/static", http.FileServer(http.Dir("./static")))
fmt.Print("server is running\n")
http.ListenAndServe(":80", nil)
}
处理函数 route.go
// route
package main
import (
"fmt"
"io"
"net/http"
"strconv"
)
func Home(w http.ResponseWriter, r *http.Request) {
fmt.Println("go")
fmt.Println(GetBest())
w.Write([]byte("hi"))
}
func Search(w http.ResponseWriter, r *http.Request) {
url := "https://www.googleapis.com/customsearch/v1?cx=项目id&safe=是否开启安全模式(active)&key=" + GetBest()
r.ParseForm()
q := r.Form["q"][0]
var p string
var t string
if r.Form["p"] != nil {
p = r.Form["p"][0]
} else {
p = ""
}
if r.Form["t"] != nil {
t = r.Form["t"][0]
} else {
t = ""
}
if q == "" {
w.Write([]byte("null"))
return
} else {
url = url + "&q=" + q
}
if p == "" {
p = "1"
} else {
i, _ := strconv.Atoi(p)
p = strconv.Itoa(i*10 + 1)
}
url = url + "&start=" + p
if t != "" {
url = url + "&siteSearch=" + t
}
fmt.Println("q= ", q, " p= ", p, " t= ", t)
client := http.Client{}
resp, err := client.Get(url)
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()
w.Header().Set("Access-Control-Allow-Origin", "*")
io.Copy(w, resp.Body)
}
多个api 获取使用次数最少api,从文件获取apis
api.go
// api
package main
import (
"bufio"
"errors"
"fmt"
"os"
"time"
)
type SeaApi struct {
apis []api
time time.Time
}
type api struct {
apiCode string
count int
}
var apii *SeaApi
//初始化
func Api() {
apii = &SeaApi{time: time.Now()}
}
func NewApi() *SeaApi {
return &SeaApi{time: time.Now()}
}
//添加api
func AddApi(a string) {
newApi := api{a, 0}
apii.apis = append(apii.apis, newApi)
}
func (s *SeaApi) AddApi(a string) {
newApi := api{a, 0}
s.apis = append(s.apis, newApi)
}
//删除指定api
func DelApi(n int) {
apii.apis = append(apii.apis[:n], apii.apis[n+1:]...)
}
func (s *SeaApi) DelApi(n int) {
s.apis = append(s.apis[:n], s.apis[n+1:]...)
}
//获取指定api
func GetApi(n int) (api, error) {
if n > len(apii.apis) {
return api{}, errors.New("fault index")
}
return apii.apis[n], nil
}
func (s *SeaApi) GetApi(n int) (api, error) {
if n > len(s.apis) {
return api{}, errors.New("fault index")
}
return s.apis[n], nil
}
//获取所有api
func GetAllApi() *SeaApi {
return apii
}
func (s *SeaApi) GetAllApi() *SeaApi {
return s
}
//从文件读取api,每行一个,文件名api.txt
func ReadApi(file string) interface{} {
f, err := os.Open(file)
if err != nil {
fmt.Print(err.Error())
return nil
}
defer f.Close()
Clear()
scan := bufio.NewScanner(f)
count := 0
for scan.Scan() {
str := scan.Text()
apii.AddApi(str)
count = count + 1
}
return count
}
func (s *SeaApi) ReadApi(file string) interface{} {
f, err := os.Open(file)
if err != nil {
fmt.Print(err.Error())
return nil
}
defer f.Close()
Clear()
scan := bufio.NewScanner(f)
count := 0
for scan.Scan() {
str := scan.Text()
s.AddApi(str)
count = count + 1
}
return count
}
//清理所有api
func Clear() {
apii.apis = apii.apis[0:0]
}
func (s *SeaApi) Clear() {
s.apis = s.apis[0:0]
}
func TimeTo() {
for {
time.Sleep(time.Duration(1) * time.Hour)
now := time.Now()
if now.Sub(apii.time).Hours() > 24 {
apii.time = now
for _, a := range apii.apis {
a.count = 0
}
}
}
}
//轮询,满24小时更新使用次数为0
func (s *SeaApi) TimeTo() {
for {
time.Sleep(time.Duration(1) * time.Hour)
now := time.Now()
if now.Sub(s.time).Hours() > 24 {
s.time = now
for _, a := range s.apis {
a.count = 0
}
}
}
}
func GetBest() string {
n := 0
for i, a := range apii.apis {
if apii.apis[n].count >= a.count {
n = i
}
}
apii.apis[n].count = apii.apis[n].count + 1
return apii.apis[n].apiCode
}
//获取使用次数最少的api
func (s *SeaApi) GetBest() string {
n := 0
for i, a := range s.apis {
if s.apis[n].count >= a.count {
n = i
}
}
s.apis[n].count = s.apis[n].count + 1
return s.apis[n].apiCode
}
3. 前端页面
html可以自己设计
主要js代码:
index.js
$(document).ready(function () {
//文本输入框监听
$("#text").keydown(function (e) {
var curKey = e.which;
if (curKey == 13) {
$("#go").click();
return false;
}
});
//搜索按钮监听
$("#go").click(function () {
var str = $("#text").val();
console.log(str);
if (str != '') window.location.href = 'search.html?q=' + str;
});
//判断是否是手机端
function IsMobile() {
var isMobile = {
Android: function () {
return navigator.userAgent.match(/Android/i) ? true : false;
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i) ? true : false;
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPad|iPod/i) ? true : false;
},
Windows: function () {
return navigator.userAgent.match(/IEMobile/i) ? true : false;
},
any: function () {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
}
};
return isMobile.any(); //是移动设备
}
var mobile_flag = IsMobile();
if (mobile_flag) {
$("#mho").attr("style","font-size: 3em;");
$("#pc1").hide();
}
})
search.js
$(document).ready(function () {
var str = GetUrlPara();
var nowPage = 0;
$("#up").hide();
$("#down").hide();
//获取请求参数
function GetUrlPara() {
var url = document.location.toString();
var arrUrl = url.split("?");
var para = arrUrl[1];
para = para.split("&");
var p0 = para[0].split("=");
return p0[1];
}
//ajax获取搜索值
function Search(query, page, type) {
query = decodeURIComponent(query);
var urls = "后台服务器ip或域名/search?q=" + query + "&p=" + page + "&t=" + type;
$("#tit").html("冒号--> " + decodeURIComponent(query));
$("#text").attr("value", decodeURIComponent(query));
urls = urls.replace(/[ ]/g,'_');
console.log(urls);
$.ajax({
type: "GET",
url: urls,
dataType: "json",
success: function (data) {
$("#loading").hide();
var str1 = '<div class="row"><div class="panel panel-default"><div class="panel-body"><p><h3><a href="';
var str2 = '">';
var str3 = '</a></h3></p><p>';
var str4 = '</p><p><a href="';
var str5 = '">';
var str6 = '</a></p></div></div></div>';
var all = '';
for (var j = 0; j < data["items"].length; j++) {
all = all + str1 + data["items"][j]["link"] + str2 + data["items"][j]["title"] + str3 + data["items"][j]["snippet"] + str4 + data["items"][j]["link"] + str5 + data["items"][j]["displayLink"] + str6;
}
$("#cont").html(all);
if (data["queries"]["nextPage"] != null) {
$("#down").show();
} else {
$("#down").hide();
}
if (nowPage != 0) {
$("#up").show();
} else {
$("#up").hide();
}
}
});
}
Search(str, 0, "");
$("#text").keydown(function (e) {
var curKey = e.which;
if (curKey == 13) {
$("#go").click();
return false;
}
});
$("#go").click(function () {
var strText = $("#text").val();
if (strText == "") {
window.location.href = 'index.html';
}
else {
window.location.href = 'search.html?q=' + strText;
}
//Search(strText,0,"");
});
$("#logo").click(function () {
window.location.href = 'index.html';
});
//回到顶部
function pageScroll() {
$('html,body').animate({
scrollTop: 0
}, 1000);
}
$("#up").click(function () {
$("#loading").show();
nowPage--;
Search(str, nowPage, "");
pageScroll();
});
$("#down").click(function () {
$("#loading").show();
nowPage++;
Search(str, nowPage, "");
pageScroll();
});
function IsMobile() {
var isMobile = {
Android: function () {
return navigator.userAgent.match(/Android/i) ? true : false;
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i) ? true : false;
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPad|iPod/i) ? true : false;
},
Windows: function () {
return navigator.userAgent.match(/IEMobile/i) ? true : false;
},
any: function () {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
}
};
return isMobile.any(); //是移动设备
}
var mobile_flag = IsMobile();
if (mobile_flag) {
$("#mho").attr("style", "font-size: 2em;text-align: center;");
}
})
4. 程序上线
我将html、js托管在coding pages上,go程序发布到美国服务器ubuntu18上,服务器开启了bbr加速,域名全部使用cloudflare,并开启了cdn功能(有缓存,调试的话先关了)。
小结
golang程序的编写,使用了许多go官方库,也踩了许多坑,但是对go 的库使用更加熟练。前端页面的编写主要用bootstrap和jquery框架,开发速度快很多,相较于以前,对这两个框架使用更加灵活,官方文档认真的看下来会发现以前没认真看真的走了好多弯路。
效果图


Golang 谷歌搜索api 实现搜索引擎(前端 bootstrap + jquery)的更多相关文章
- Python + Bottle + 谷歌搜索Api 实现简单搜索引擎
1.运行环境 python3 centos7 2.Bottle的使用 使用bottle主要是因为它仅用python自带的库即可实现对web的搭建. bottle源码分析 bottle使用教程 3.代码 ...
- ASP.NET实现二维码 ASP.Net上传文件 SQL基础语法 C# 动态创建数据库三(MySQL) Net Core 实现谷歌翻译ApI 免费版 C#发布和调试WebService ajax调用WebService实现数据库操作 C# 实体类转json数据过滤掉字段为null的字段
ASP.NET实现二维码 using System;using System.Collections.Generic;using System.Drawing;using System.Linq;us ...
- jsonp跨越请求百度搜索api 实现下拉列表提示
题目来源: 最近在做百度IFE前端技术学院的题,然后有一题就是模拟百度搜索智能提示.题目是开源的,稍后给出地址. 因为博主没学过后端啊,欲哭无泪,所以不能实现后端模糊搜索,那如果前端ajax纯粹请求一 ...
- 基于asp.net(C#)MVC+前端bootstrap+ztree+lodash+jquery技术-Angel工作室通用权限管理
一.Angel工作室简单通用权限系统简介 AngelRM(Asp.net MVC Web api)是基于asp.net(C#)MVC+前端bootstrap+ztree+lodash+jquery技术 ...
- 使用Javascript从Google Places搜索api获取纬度和经度
如何使用谷歌地图搜索框api从搜索到的位置获取经度和纬度. 我使用与谷歌演示相同的代码 – https://developers.google.com/maps/documentation/javas ...
- Google的搜索API的Delphi封装
这个东西实现了已经有一段时间了,那个时候谷歌还没有退出中国内地呢!而现在呢,谷歌都退了有一些日子了!紧以此纪念一番! 话说谷歌API,我相信很多人应该都知道!不晓得在实际应用中,用的人多不多(我说的不 ...
- Lucene.net站内搜索—5、搜索引擎第一版实现
目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...
- Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)
目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...
- 百度音乐搜索API介绍
百度音乐搜索API的请求地址如下: [html] view plaincopy http://box.zhangmen.baidu.com/x?op=12&count=1&title= ...
随机推荐
- layui实现下拉分类多级
Layui tree 下拉菜单树 1.效果: 2.html 代码: <!DOCTYPE html> <html> <head> <meta charse ...
- python bbs项目代码分析
def index(request, *args, **kwargs): condition={} type_id = int(kwargs.get("type_id")) if ...
- Linux unzip用法
1.把文件解压到当前目录下 unzip test.zip 2.如果要把文件解压到指定的目录下,需要用到-d参数. unzip -d /temp test.zip 3.解压的时候,有时候不想覆盖已经存在 ...
- IO扩展芯片
PCF8574:一个I2C接口+INT中断引脚口扩展出一个可输出输出的并口P0~P7,INT可以用于中断响应
- hbase按照时间戳删除记录
1.按照时间戳范围查询记录 echo "scan 'event_log', { COLUMN => 'cf:sid', TIMERANGE => [1466265600272, ...
- 在ubuntu 12.04上安装tomcat 7.40
因为源上的版本问题,所以没有使用源上的自动安装包,老规矩,Tomcat 7.0.40 Core下载地址:http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/ ...
- Redis的数据类型(Strings、 hashes)
字符串(Strings)类型及操作 字符串是Redis值的最基础的类型,一个key对应一个value,Redis字符串是二进制安全的,这意味着一个Redis字符串可以包含任何种类的数据,例如一个JPE ...
- gulp运行步骤
一.运行→输入cmd→跳出命令窗口二.cd D: 敲回车进入D盘,cd www 进入项目路径 cd mygulp三.执行 cnpm install gulp --save-dev 命令 (初始化安装g ...
- Appium基础二:Appium的安装(基Windows)
1.JAVA环境配置: 1.1安装jdk: 1.2配置JAVA_Home.Path配置.java验证 Path: 输入C:\Program Files\Java\jdk1.8.0_121\bin:C: ...
- redis 大批量数据插入导致MISCONF Redis is configured to save RDB snapshots的解决
PS:之前写过一遍,那个方法没有彻底解决,现找到真正的解决方法 环境:redis 3.2.100 windows版(注意!!!这是关键),win10,redis客户端spring boot 2.0.7 ...