基于How To Tango With Django 1.9的重新实践(14)——Bing Search

本文介绍如何将Bing搜索API集成到Django应用Rango中,包括注册API密钥、编写搜索功能代码及整合搜索功能到Rango应用的具体步骤。

在这个阶段,我们的Rango看起来已经非常好啦 - 大部分的功能都已经实现了,在这章,我们将为我们的Rango提供Bing的搜索的功能而不是仅仅使用目录.首先让我们先设置一个Bing账户来使用它的API,然后把Bing搜索集成进Rango.

14.1 Bing搜索API

Bing搜索API提供了在你的应用中嵌入搜索结果的功能.通过简单的交互,你可以从Bing的服务器返回一个XML或者JSON.这个数据可以通过XML或者JSON解析器进行解析,最后结果传递给你的模板进行调用.

尽管Bing的API可以处理不同内容的请求,我们只需要关注本教程使用的部分 - 就是处理响应的JSON.为了使用Bing搜索的API,你需要注册一个API key.这个key可以给用户每个月5000次请求的权限,对于我们个人用户来说足够用了.

14.1.1 注册一个API key

为了注册一个Bing API key,你必须首先注册一个免费的Microsoft账户.这个账户提供了许多的Microsoft服务.如果你已经有一个Hotmail账户,那么就不用再注册了.你可以在这里 https://account.windowsazure.com 注册和登录帐号.

当你创建完帐号,访问 Windows Azure Marketplace Bing Search API page.在页面的顶部你需要点击Sign In按钮 - 如果你已经你已经进入到Microsoft账户(上面写着Sing Out),就不需要再登录了.

页面右边的列表是每月的事务量.在最顶部是5000/月.点击右边的注册按钮 - 你将会订阅一个免费的服务.阅读完有关条例以后,如果同意条款点击注册按钮继续.接下来将会显示成功注册的页面.

注册成功以后,点击页面顶部的数据链接.在这里你将会看到Windows Azure Marketplace的可用资源列表.在这个列表顶部应当是Bing Search API - 同时右边显示的是你已订阅该资源.点击位于右边的使用.你将会看到如下图所示的页面.

14.2 增加搜索功能

为了增加Rango的搜索功能,我们必须增加一个Bing API查询语句.这个代码将会从一个特定的用户获取请求,并返回一个列表作为结果.所有在API查询阶段的错误都能被很好的处理.拆分这个搜索函数作为添加函数可以有效的分离Django代码和搜索函数代码.

开始,在rango应用目录里添加一个新的Python模块bing_search.py.代码如下.注意查看注释的内容:

import json
import http.client, urllib.request, urllib.parse, urllib.error, base64
#将Microsoft账户的Key添加到一个名为bing.key的文件

def read_bing_key():
    '''
    读取BING API的key从一个名为bing_key.txt的文件
    返回一个string或者None(没有找到key)
    记得把bing.key文件放到你的.gitignore文件中,以避免提交到公共仓库
    '''

    bing_api_key = None
    try:
        with open('bing_key','r') as f:
            bing_api_key = f.readline()

    except:
        raise IOError('bing_key.txt file not found')

    return bing_api_key

def run_query(search_terms):
    '''
    给定一个包含搜索词(查询)的string,
    返回Bing搜索引擎中的结果list
    '''
    #bing_api_key = str(read_bing_key())
    bing_api_key = '????'

    if not bing_api_key:
        raise KeyError('Bing Key Not Found')

    headers={
        'Ocp-Apim-Subscription-Key': bing_api_key,
    }

    '''
    #指定基本的url和服务
    root_url = 'https://api.cognitive.microsoft.com/bing/v5.0/search/'
    service = 'Web'


    #指定我们希望每页返回多少结果
    #offset指定从结果list开始的位置
    #With results_per_page = 10 and offset = 11,这将从第二页开始
    results_per_page = 10
    offset = 0
    '''

    #根据Bing API的要求,需要在查询字词的周围加上引号
    #我们将使用query这个变量储存我们的查询
    query = "'{0}'".format(search_terms)

    '''
    #使用urllib将query转换为HTML编码字符串。
    query = urllib.parse.quote(query)
    '''

    '''
    #构造请求网址的后半部分
    #将相应的合适设置为JSON并设置其他属性
    search_url = "{0}{1}?$format=json&$top={2}&$skip={3}&Query={4}".format(
        root_url,
        service,
        results_per_page,
        offset,
        query
    )
    '''

    params = urllib.parse.urlencode({
        # Request parameters
        'q': query,
        'count': '10',
        'offset': '0',
        'mkt': 'en-us',
        'safesearch': 'Moderate',
    })
    '''
    #使用Bing服务器设置身份验证
    #用户名必须是空字符串,并放入您的API密钥
    username=''


    #设置密码管理器以帮助验证我们的请求
    password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()

    password_mgr.add_password(None,search_url,username,bing_api_key)
    '''

    #创建我们将填充的结果list
    results = []

    try:
        #准备连接Bing的服务
        conn = http.client.HTTPSConnection('api.cognitive.microsoft.com')

        # 连接到服务器并读取生成的响应
        conn.request("GET", "/bing/v5.0/search?%s" % params, "{body}", headers)
        response = conn.getresponse().read()
        response = response.decode('utf-8')

        conn.close()

        #将字符串响应转换为Python字典对象
        json_response = json.loads(response)

        #循环每个返回页面,填充结果list
        for result in json_response['webPages']['value']:
            results.append({'title': result['name'],
                            'link': result['url'],
                            'summary': result['snippet']})
    except:
        print("Error when querying the Bing API")

    return results


def main():
    print("Enter a query:")
    query = input()
    results = run_query(query)

    for result in results:
        print(result['title'])
        print('-'*len(result['title']))
        print(result['summary'])
        print(result['link'])
        print()


if __name__ == '__main__':
    main()





14.3 把搜索放入Rango

为了加入外部搜索我们需要进行以下几步.

  1. 我们需要创建一个继承自base.html模板的search.html模板.这个模板将会包含一个HTML<form>来获取用户输入的请求,然后会程序返回的结果.
  2. 然后我们创建一个视图来处理search.html模板传递给我们的参数,然后调用我们上面定义的run_query()函数.

14.3.1 加入搜索模板

让我们现建立一个search.html模板.代码如下.

{% extends 'rango/base.html' %}
{% load staticfiles %}

{% block title %}
    Search
{% endblock %}
{% comment %}
    1.在所有情况下,它都会展现一个搜索框<input>和一个搜索按钮<button>,使用一个HTML<form>来供用户输入并发送查询语句.
    2.当results_list传递给模板上下文时,模板将会展示它包含的所有结果.
{% endcomment %}
{% block body_block %}
<div>
    <h1>Search with Rango</h1>
    <br>
    <form action="{% url 'search' %}" class="form-inline" id="user_form" method="post">
        {% csrf_token %}
        <div class="form-group">
            <input type="text" class="form-control" size="50" name="query" value="" id="query">
        </div>
        <button class="btn btn-primary" type="submit" name="submit" value="Search">Search</button>
    </form>
    <div>
        {% if result_list %}
        <h3>Results</h3>
        <!-- 展示搜索的结果在一个有序的list中 -->
        <div class="list-group">
            {% for result in result_list %}
            <div class="list-group-item">
                <h4 class="list-group-item-heading">
                    <a href="{{ result.link }}">{{ result.title }}</a>
                </h4>
                <p class="list-group-item-text">{{ result.summary }}</p>
            </div>
            {% endfor %}
        </div>
        {% endif %}
    </div>
</div>
{% endblock %}

14.3.2 添加视图
添加完搜索模板后,我们可以添加视图了.在views.py模块里添加下面search()视图.

def search(request):
    result_list = []
    if request.method == 'POST':
        query = request.POST['query'].strip()
        if query:
            #使用我们的Bing功能来得到结果list
            result_list = run_query(query)

    return render(request,'rango/search.html',{'result_list':result_list})

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值