Python + Bottle + 谷歌搜索Api 实现简单搜索引擎

1.运行环境

  1. python3
  2. centos7

2.Bottle的使用

使用bottle主要是因为它仅用python自带的库即可实现对web的搭建。
bottle源码分析
bottle使用教程

3.代码

#app.py
from bottle import route, run ,Bottle ,error ,static_file ,request 
from bottle import view , template 

from app import search
from data import db
import json

#import views

#实例化一个app
app = Bottle()
#读取api数据
data = db.data()
data.read()

@app.route('/')
@view("home")
def index():
    """
    首页
    """
    return #template('home')

@app.route('/<query>')
@view("search")
def query(query):
    """
    执行查询操作:/关键词
    """
    global data
    key = data.touch()
    res = search.query(query,key)
    res = json.loads(res)
    return res


@app.route('/api/<query>')
def apiQuery(query):
    """
    查询接口的api,返回json数据
    """
    global data
    key = data.touch()
    res = search.apiQuery(query,key)
    #res = json.loads(res)
    return res

@app.route('/man/getall')
def manGetall():
    """
    获取所有api信息
    """
    global data
    #res = json.loads(res)
    list = data.getAll()
    res = ''
    for i in list:
      res = res + i[0] + " " + i[1] + "<br>"
    print(res)
    return res

@app.route('/search')
@view("search")
def query2():
    """
    另一种搜索传参方式:q=关键词
    """
    global data
    key = data.touch()
    q = request.query.q
    #print(q)
    res = search.query(q,key)
    res = json.loads(res)
    return res

@error(404)
def error404(error):
    """
    404
    """
    return 'Nothing here, sorry'

@app.route('/static/<filename>')
def server_static(filename):
    """
    静态文件返回数据
    """
    #print("***")
  	#filename = filename + ".ico"
    return static_file(filename, root='./static')

app.run(host='localhost', port=9090)
#search.py
import urllib
import urllib.request
from urllib import parse
import json

#指定站点搜索:siteSearch

def query(q,key):
    url = 'https://www.googleapis.com/customsearch/v1?cx=012564558536199079522:s1cewzl004i&safe=active&key='
    q = parse.quote(q)
    url = url + key + "&q=" + q
    resB = urllib.request.urlopen(url)
    res = resB.read().decode('utf-8')
    return res


def apiQuery(q,key):
    url = 'https://www.googleapis.com/customsearch/v1?cx=012564558536199079522:s1cewzl004i&safe=active&key='
    q = parse.quote(q)
    url = url + key + "&q=" + q
    resB = urllib.request.urlopen(url)
    res = resB.read().decode('utf-8')
    return res


#db.py
class data:

    def read(self):
        fp = open("data//data.txt",encoding="utf-8")
        '''
        #方法一
        line = fp.readline()
        print(line)
        key = []
        i = 0

        while(line):
            str = line.split()
            #print("***")
            #print(str)
            key.append(str) 
            line = fp.readline()
            i = i + 1

        self.key = key
        fp.close()'''
        #方法二
        key = []
        str = fp.read()
        tmp = str.split("
")
        for i in range(len(tmp)):
            key.append(tmp[i].split())
        self.key = key
        fp.close()
        #print(key)

    def write(self):
        """
        保存api key
        """
        key = self.key
        fp = open("data//data.txt","w+")
        for i in range(len(key)):
            fp.writelines(key[i][0]+" "+key[i][1])
        fp.close()

    def touch(self):
        """
        随机获取一个api key
        """
        key = self.key
        k = 0
        for i in range(len(key)):
            if(key[k][1]>key[i][1]):
                k = i
        x = key[k][1]
        key[k][1] = (str)(1 + (int)(x))
        #key[k][i] += 1
        return key[k][0]

    def getAll(self):
        """
        获取所有api key
        """
        return self.key

    def add(self,list):
        """
        添加api key
        """
        self.key.append(list)

    def delOne(self,index):
        """
        删除一个 api key
        """
        self.key.pop(index)
#home.tpl
<!DOCTYPE html>
<html>
  <head>
<meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="">
<title>冒号--www.mho.cx</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
 
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
 
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="shortcut icon" href="static/fa.ico" />
  </head>
  <body>

    	<div class="panel panel-default container navbar-static-top" style="max-900px;">
		<div class="panel-body">
          <h3 class="text-center"><a href="https://www.mho.cx">冒号搜索</a></h3>
					<form class="bs-example bs-example-form container" style="max-800px;" role="form" method="get" action="https://mho.cx/search">
						<div class="input-group">
                          	
                            
							<input type="text" class="form-control"  placeholder="发现这个世界!"  name="q"  >
							<span class="input-group-btn">
								<button class="btn btn-default" type="summit">
									GO!
								</button>
                              </span>
                          
						</div>
					</form>
		</div>
	</div>
    <div class="panel panel-default container" style="max-900px;">
		<div class="panel-body">
    <img src="http://img.zcool.cn/community/010b9c57748a930000012e7e419c08.png@2o.png" style="100%;">
          </div>
          </div>
  
<div class="panel panel-default container navbar-static-bottom" style="max-900px;">
	<div class="panel-body">
		<h5 class="text-center"><a href="https://www.mho.cx">&copy;2019 冒号:</a></h3>
	</div>
</div>
    
  </body>
</html>

#search.tpl
<!doctype html>
<html>

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="">
	<title>冒号:搜索->
		{{queries['request'][0]['searchTerms']}}
	</title>
	<!-- 新 Bootstrap 核心 CSS 文件 -->
	<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

	<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

	<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
	<link rel="shortcut icon" href="static/fa.ico" />
</head>

<body>

	<div class="panel panel-default navbar-fixed-top">
		<div class="panel-heading">
			<h3 class="panel-title text-center"><a href="http://www.mho.cx">冒号搜索</a></h3>
		</div>
		<div class="panel-body">
			<form class="bs-example bs-example-form container" role="form" style="max-800px;" method="get" action="https://mho.cx/search">
				<div class="input-group">
					<input type="text" class="form-control" placeholder="发现这个世界!" name="q" value="{{queries['request'][0]['searchTerms']}}">
					<span class="input-group-btn">
						<button class="btn btn-default" type="summit">
							GO!
						</button>
					</span>
				</div>
			</form>
		</div>
	</div>

	<div class="panel panel-default">
		<div class="panel-heading">
			<h3 class="panel-title text-center"><a href="https://www.mho.cx">冒号搜索</a></h3>
		</div>
		<div class="panel-body">
			<form class="bs-example bs-example-form container" style="max-800px;" role="form" method="get" action="https://mho.cx/search">
				<div class="input-group">
					<input type="text" class="form-control" placeholder="发现这个世界!" name="q" value="{{queries['request'][0]['searchTerms']}}">
					<span class="input-group-btn">
						<button class="btn btn-default" type="button">
							GO!
						</button>
					</span>
				</div>
			</form>
		</div>
	</div>

	%if queries['request'][0]['totalResults']!="0":
	<div class="panel panel-default">
		<div class="panel-body">
			%for i in items:
			<div class="well container" style="max-800px;">
				<p>
					<h4><a href="{{i['link']}}" target="_blank">{{i['title']}}</a></h4>
				</p>
				<p><strong>{{i['snippet']}}</strong></p>
				<p>{{i['displayLink']}}</p>
			</div>
			%end
		</div>
	</div>
	%else:
	<div class="panel panel-default">
		<div class="panel-body">
			<div class="well container" style="max-800px;">
				<p>
					<h4>Sorry , no found</h4>
				</p>
			</div>
		</div>
	</div>
	%end

	<div class="panel panel-default container navbar-static-bottom" style="max-800px;">
		<div class="panel-body">
			<h5 class="text-center"><a href="https://www.mho.cx">&copy;2019 冒号:</a></h3>
		</div>
	</div>

</body>

</html>
原文地址:https://www.cnblogs.com/boxker/p/10610630.html