狠狠撸

狠狠撸Share a Scribd company logo
TwD Chapter 12
Adding External
Search Functionality
asika Kuo
For Django Summer
Django Summer 2
12. Adding External Search
Functionality
●
本章要利用 Bing API 替 APP 增加搜尋功能
Django Summer 3
12.1. The Bing Search API
●
把用 Bing 搜尋到的資料顯示在自己的 APP 裡
●
Bing 伺服器回傳的 result 可以是 XML 或 JSON (可以自己
指定)
Django Summer 4
12.1.1. Registering for a Bing API Key
●
註冊 MS 的帳號(可以直接用 hotmail 的)
– https://account.windowsazure.com
●
到 Windows Azure Marketplace Bing Search API page 訂
閱免費版搜尋 API 服務
– 5,000 Transactions/month
Django Summer 5
12.2. Adding Search Functionality
●
建立 rango/bing_search.py
Django Summer 6
12.2. Adding Search Functionality
●
根據 API 的規定準備
好我們要送出的
request 字串
def run_query(search_terms):
root_url =
'https://api.datamarket.azure.com/Bing/Search/'
source = 'Web'
results_per_page = 10
offset = 0
query = "'{0}'".format(search_terms)
query = urllib.quote(query)
search_url = "{0}{1}?
$format=json&$top={2}&$skip={3}&Query={4}".format(
root_url,
source,
results_per_page,
offset,
query)
Django Summer 7
12.2. Adding Search Functionality
●
利用 urllib2 的
password manager
在送出的 HTTP
request header 中加
入我們剛申請好的
API Key 資訊
●
# Setup authentication with the Bing servers.
# The username MUST be a blank string, and put in
your API key!
username = ''
bing_api_key = '<api_key>'
# Create a 'password manager' which handles
authentication for us.
password_mgr =
urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, search_url,
username, bing_api_key)
Django Summer 8
● HTTP Basic Authentication
– 在用戶端發送 request 時一併於 HTTP header 提供用戶名和密碼的一
種簡易認證方式
– 預設會將 <username>:<password> 用 Base64 編碼後送出
●
不是為了安全性而是為了轉換掉與 HTTP 不相容的字元
●
Bing 規定的 API Key 認證方式
– Username: 空字串
– Password: 申請到的 API Key
Django Summer 9
12.2. Adding Search Functionality
●
用 urllib2.openurl()
連同 query string 和
認證資訊一起送出
●
接到的 response 會
是字串格式的 JSON
●
用 json.loads() 轉成
python dictionary
# Prepare for connecting to Bing's servers.
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
# Connect to the server and read the response generated.
response = urllib2.urlopen(search_url).read()
# Convert the string response to a Python dictionary object.
json_response = json.loads(response)
# Loop through each page returned, populating out results list.
for result in json_response['d']['results']:
results.append({
'title': result['Title'],
'link': result['Url'],
'summary': result['Description']})
Django Summer 10
12.3. Putting Search into Rango
●
建立
templates/rango/se
arch.html
– 如果有傳入
result_list 就把內
容 render 到頁面
上
{% if result_list %}
<!-- Display search results in an ordered list -->
<div style="clear: both;">
<ol>
{% for result in result_list %}
<li>
<strong><a
href="{{ result.link }}">{{ result.title }}</a></strong>
<br />
<em>{{ result.summary }}</em>
</li>
{% endfor %}
</ol>
</div>
{% endif %}
Django Summer 11
12.3.2. Adding the View
def search(request):
context = RequestContext(request)
result_list = []
if request.method == 'POST':
query = request.POST['query'].strip()
if query:
# Run our Bing function to get the
results list!
result_list = run_query(query)
return
render_to_response('rango/search.html',
{'result_list': result_list}, context)
Django Summer 12
處理 Unicode
● run_query() 預設處理的格式是 str
– query = "'{0}'".format(search_terms)
● 從前端傳回來的 query string 是 unicode
– 包含英文以外的字元, format() 就會發生
UnicodeEncodeError
● 解法
– 呼叫 unicode 的 format()
● query = u"'{0}'".format(search_terms)
●
Django Summer 13
處理 Unicode
● urllib.quote() 傳入 unicode 字串發生 KeyError
● 解法
– 把 query 字串編碼為 UTF-8
– query = urllib.quote(query.encode('utf-8'))

More Related Content

tangowithdjango - Ch12

  • 1. TwD Chapter 12 Adding External Search Functionality asika Kuo For Django Summer
  • 2. Django Summer 2 12. Adding External Search Functionality ● 本章要利用 Bing API 替 APP 增加搜尋功能
  • 3. Django Summer 3 12.1. The Bing Search API ● 把用 Bing 搜尋到的資料顯示在自己的 APP 裡 ● Bing 伺服器回傳的 result 可以是 XML 或 JSON (可以自己 指定)
  • 4. Django Summer 4 12.1.1. Registering for a Bing API Key ● 註冊 MS 的帳號(可以直接用 hotmail 的) – https://account.windowsazure.com ● 到 Windows Azure Marketplace Bing Search API page 訂 閱免費版搜尋 API 服務 – 5,000 Transactions/month
  • 5. Django Summer 5 12.2. Adding Search Functionality ● 建立 rango/bing_search.py
  • 6. Django Summer 6 12.2. Adding Search Functionality ● 根據 API 的規定準備 好我們要送出的 request 字串 def run_query(search_terms): root_url = 'https://api.datamarket.azure.com/Bing/Search/' source = 'Web' results_per_page = 10 offset = 0 query = "'{0}'".format(search_terms) query = urllib.quote(query) search_url = "{0}{1}? $format=json&$top={2}&$skip={3}&Query={4}".format( root_url, source, results_per_page, offset, query)
  • 7. Django Summer 7 12.2. Adding Search Functionality ● 利用 urllib2 的 password manager 在送出的 HTTP request header 中加 入我們剛申請好的 API Key 資訊 ● # Setup authentication with the Bing servers. # The username MUST be a blank string, and put in your API key! username = '' bing_api_key = '<api_key>' # Create a 'password manager' which handles authentication for us. password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password(None, search_url, username, bing_api_key)
  • 8. Django Summer 8 ● HTTP Basic Authentication – 在用戶端發送 request 時一併於 HTTP header 提供用戶名和密碼的一 種簡易認證方式 – 預設會將 <username>:<password> 用 Base64 編碼後送出 ● 不是為了安全性而是為了轉換掉與 HTTP 不相容的字元 ● Bing 規定的 API Key 認證方式 – Username: 空字串 – Password: 申請到的 API Key
  • 9. Django Summer 9 12.2. Adding Search Functionality ● 用 urllib2.openurl() 連同 query string 和 認證資訊一起送出 ● 接到的 response 會 是字串格式的 JSON ● 用 json.loads() 轉成 python dictionary # Prepare for connecting to Bing's servers. handler = urllib2.HTTPBasicAuthHandler(password_mgr) opener = urllib2.build_opener(handler) urllib2.install_opener(opener) # Connect to the server and read the response generated. response = urllib2.urlopen(search_url).read() # Convert the string response to a Python dictionary object. json_response = json.loads(response) # Loop through each page returned, populating out results list. for result in json_response['d']['results']: results.append({ 'title': result['Title'], 'link': result['Url'], 'summary': result['Description']})
  • 10. Django Summer 10 12.3. Putting Search into Rango ● 建立 templates/rango/se arch.html – 如果有傳入 result_list 就把內 容 render 到頁面 上 {% if result_list %} <!-- Display search results in an ordered list --> <div style="clear: both;"> <ol> {% for result in result_list %} <li> <strong><a href="{{ result.link }}">{{ result.title }}</a></strong> <br /> <em>{{ result.summary }}</em> </li> {% endfor %} </ol> </div> {% endif %}
  • 11. Django Summer 11 12.3.2. Adding the View def search(request): context = RequestContext(request) result_list = [] if request.method == 'POST': query = request.POST['query'].strip() if query: # Run our Bing function to get the results list! result_list = run_query(query) return render_to_response('rango/search.html', {'result_list': result_list}, context)
  • 12. Django Summer 12 處理 Unicode ● run_query() 預設處理的格式是 str – query = "'{0}'".format(search_terms) ● 從前端傳回來的 query string 是 unicode – 包含英文以外的字元, format() 就會發生 UnicodeEncodeError ● 解法 – 呼叫 unicode 的 format() ● query = u"'{0}'".format(search_terms) ●
  • 13. Django Summer 13 處理 Unicode ● urllib.quote() 傳入 unicode 字串發生 KeyError ● 解法 – 把 query 字串編碼為 UTF-8 – query = urllib.quote(query.encode('utf-8'))