今天因為測試 OpenAI API 需要用到 Google 搜尋來詢問與時事相關問題時, 發現之前使用的 googlesearch-python 套件沒有傳回任何結果 :
>>> from googlesearch import search
>>> keywords='2024台灣總統大選是誰當選?'
>>> items=search(keywords, advanced=True, num_results=3)
>>> for item in items:
print(f'標題:{item.title}')
print(f'標題:{item.description}')
print(f'標題:{item.url}\n')
執行結果是空白, 詢問 ChatGPT 答覆是此套件可能已經無法使用, 建議使用 SerpAPI 來取得谷歌搜尋結果, 但必須先註冊帳號取得 API Key 才能使用.
1. 註冊 SerpAPI 帳號 :
到 SerpAPI 官網按右上角的 "Register" 註冊帳號, 免費帳戶每個月可搜尋 100 次 (平均一天只能使用 33 次, 好像有點小氣) :
可以用 Google 或 GitHub 帳號快速註冊, 但我習慣用 Hinet 郵件註冊, 填好姓名, Email 與設定密碼後按底下的 Sign Up 鈕, 它會寄一封驗證信到信箱, 去信箱收信並按下信中的確認超連結 :
這時會開啟電話驗證頁面, 在底下 Verification code 欄位中先點前面的國籍選擇台灣, 然後輸入自己的手機號碼, 按 Send Code 鈕 :
然後收取手機簡訊, 將 6 碼驗證碼貼到 Verification code 欄後按 Verify 鈕 :
按底下的 Subscribe 鈕即完成註冊並顯示 Dashboard 頁面 :
往下拉到 Your private API Key 就可以看到使用 API 所需的金鑰, 按右邊的按鈕複製到文字檔中保存備用 :
有了 API Key 接下來要安裝 API 的套件.
2. 安裝 google-search-results 套件 :
用 pip 安裝 google-search-results 套件 :
D:\python\test>pip install google-search-results
Collecting google-search-results
Downloading google_search_results-2.4.2.tar.gz (18 kB)
Preparing metadata (setup.py) ... done
Requirement already satisfied: requests in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-search-results) (2.31.0)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->google-search-results) (3.2.0)
Requirement already satisfied: idna<4,>=2.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->google-search-results) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from requests->google-search-results) (1.26.19)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->google-search-results) (2023.7.22)
Building wheels for collected packages: google-search-results
Building wheel for google-search-results (setup.py) ... done
Created wheel for google-search-results: filename=google_search_results-2.4.2-py3-none-any.whl size=32077 sha256=6675aa38f27d33c50a5ce0f9af5d634abe719b015fe63b2326a5a926094321fe
Stored in directory: c:\users\tony1\appdata\local\pip\cache\wheels\d3\b2\c3\03302d12bb44a2cdff3c9371f31b72c0c4e84b8d2285eeac53
Successfully built google-search-results
Installing collected packages: google-search-results
Successfully installed google-search-results-2.4.2
雖然安裝的套件名稱是, 但匯入使用時卻要用 serpapi 這個套件名稱 :
>>> import serpapi
用 dir() 檢視套件內容 :
>>> dir(serpapi)
['AppleAppStoreSearch', 'BaiduSearch', 'BingSearch', 'DuckDuckGoSearch', 'EbaySearch', 'GoogleScholarSearch', 'GoogleSearch', 'HomeDepotSearch', 'NaverSearch', 'SerpApiClient', 'WalmartSearch', 'YahooSearch', 'YandexSearch', 'YoutubeSearch', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'apple_app_store_search', 'baidu_search', 'bing_search', 'constant', 'duck_duck_go_search', 'ebay_search', 'google_scholar_search', 'google_search', 'home_depot_search', 'naver_search', 'pagination', 'serp_api_client', 'serp_api_client_exception', 'walmart_search', 'yahoo_search', 'yandex_search', 'youtube_search']
可見此 API 套件支援非常多搜尋引擎, 除了 Google 外還可以搜尋 DuckDuckGo, Bin, Yahoo 等, 但本篇只會用到其中的 GoogleSearch 類別 :
>>> type(serpapi.GoogleSearch)
<class 'type'>
3. 用 GoogleSearch 物件搜尋 :
首先從 serpapi 匯入 GoogleSearch 類別 :
>>> from serpapi import GoogleSearch
然後呼叫其建構式 GoogleSearch() 並傳入一個參數字典 params 來建立一個 GoogleSearch 物件 :
GoogleSearch(params)
此 params 參數字典的常用鍵值如下表所示 :
參數名稱 | 說明 |
---|---|
q | 搜尋關鍵字, 例如 "2024台灣總統大選" |
num | 設定結果數量 (最多 100), 例如 num=10 取得 10 筆結果 |
start | 設定從第幾筆開始 (用於分頁), 例如 start=10 從第 11 筆開始 |
gl | 設定國家代碼, 例如 "tw" ( 台灣), "us" ( 美國) |
hl | 設定語言,例如 "zh-TW" ( 繁體中文), "en" ( 英文) |
safe | 是否啟用安全搜尋, 例如 "active" ( 開啟), "off" (關閉) |
api_key | SerpAPI 提供的 API Key, 例如 "你的 API Key" |
例如搜尋 2024 台灣總統當選人 :
>>> params={
'q': '2024台灣總統大選是誰當選?',
'api_key': '我的 API Key',
'num': 3,
'gl': 'tw',
'hl': zh-tw'
}
將其傳入 GoogleSearch() 建立一個 GoogleSearch 物件 :
>>> search=GoogleSearch(params)
>>> type(search)
<class 'serpapi.google_search.GoogleSearch'>
用 dir() 檢視 GoogleSearch 物件成員 :
>>> dir(search)
['BACKEND', 'SERP_API_KEY', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'construct_url', 'engine', 'get_account', 'get_dict', 'get_dictionary', 'get_html', 'get_json', 'get_location', 'get_object', 'get_raw_json', 'get_response', 'get_results', 'get_search_archive', 'make_pyobj', 'pagination', 'params_dict', 'timeout']
可以呼叫所提供的 get_xxx() 方法取得搜尋結果, 例如呼叫 get_dict() 會取得字典型態之結果 :
>>> results=search.get_dict()
>>> type(results)
<class 'dict'>
用 keys() 方法檢視此字典之鍵 :
>>> results.keys()
dict_keys(['search_metadata', 'search_parameters', 'search_information', 'organic_results', 'related_searches', 'pagination', 'serpapi_pagination'])
搜尋結果主要是放在 organic_results 這個鍵裡面, 此鍵主要儲存 Google 搜尋主要的自然搜尋結果 (即非廣告的結果) :
>>> results['organic_results']
[{'position': 1, 'title': '第16任總統副總統選舉', 'link': 'https://db.cec.gov.tw/ElecTable/Election/ElecTickets?dataType=tickets&typeId=ELC&subjectId=P0&legisId=00&themeId=4d83db17c1707e3defae5dc4d4e9c800&dataLevel=C&prvCode=00&cityCode=000&areaCode=00&deptCode=000&liCode=0000', 'redirect_link': 'https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://db.cec.gov.tw/ElecTable/Election/ElecTickets%3FdataType%3Dtickets%26typeId%3DELC%26subjectId%3DP0%26legisId%3D00%26themeId%3D4d83db17c1707e3defae5dc4d4e9c800%26dataLevel%3DC%26prvCode%3D00%26cityCode%3D000%26areaCode%3D00%26deptCode%3D000%26liCode%3D0000&ved=2ahUKEwjBq-zWyKGMAxXtSzABHd6WD6oQFnoECB4QAQ', 'displayed_link': 'https://db.cec.gov.tw › ElecTable › Election › ElecTickets', 'favicon': 'https://serpapi.com/searches/67e0b597a87cda1dbcb7f08f/images/f9b7843ebcee3773ad58dd96752619e182d6d5ca2488e6e49be838c999102248.png', 'snippet': '第16任總統副總統選舉 ; 金門縣. 柯文哲. /吳欣盈. 賴清德. /蕭美琴. 侯友宜. /趙少康. 1. 2. 3. 13,038. 4,569. 28,005. 28.58%. 10.02%. 61.40% ; 基隆市. 柯文哲. /吳欣盈.', 'snippet_highlighted_words': ['總統選舉'], 'source': '選舉資料庫'}, {'position': 2, 'title': '2024年中華民國總統選舉', 'link': 'https://zh.wikipedia.org/zh-tw/2024%E5%B9%B4%E4%B8%AD%E8%8F%AF%E6%B0%91%E5%9C%8B%E7%B8%BD%E7%B5%B1%E9%81%B8%E8%88%89', 'redirect_link': 'https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://zh.wikipedia.org/zh-tw/2024%25E5%25B9%25B4%25E4%25B8%25AD%25E8%258F%25AF%25E6%25B0%2591%25E5%259C%258B%25E7%25B8%25BD%25E7%25B5%25B1%25E9%2581%25B8%25E8%2588%2589&ved=2ahUKEwjBq-zWyKGMAxXtSzABHd6WD6oQFnoECCAQAQ', 'displayed_link': 'https://zh.wikipedia.org › zh-tw › 2024年中華民國總統...', 'favicon': 'https://serpapi.com/searches/67e0b597a87cda1dbcb7f08f/images/f9b7843ebcee3773ad58dd96752619e16639a9f527bc1f87bab180ae788ac04d.png', 'snippet': '本次是繼2000年後再度未有任一候選人得票率過半的總統選舉,亦是自總統直選以來,首度由同一政黨連續三次獲勝。蔡英文八年執政雖成功交棒,但維持執政地位的民進黨則在同日 ...', 'snippet_highlighted_words': ['總統選舉'], 'source': '维基百科'}, {'position': 3, 'title': '2024 總統大選即時開票', 'link': 'https://event.gvm.com.tw/2024presidential_election/votingresults_president.html', 'redirect_link': 'https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://event.gvm.com.tw/2024presidential_election/votingresults_president.html&ved=2ahUKEwjBq-zWyKGMAxXtSzABHd6WD6oQFnoECCIQAQ', 'displayed_link': 'https://event.gvm.com.tw › votingresults_president', 'favicon': 'https://serpapi.com/searches/67e0b597a87cda1dbcb7f08f/images/f9b7843ebcee3773ad58dd96752619e162d8bff986619777e960b531be99ef7f.png', 'snippet': '2024總統大選在即,在賴清德、侯友宜、柯文哲競逐的局勢下,最終誰會拿下總統大位?台灣會迎來新一次的政黨輪替嗎?《遠見》統合各候選人政見,針對選戰熱門關鍵字、候選人 ...', 'snippet_highlighted_words': ['2024總統大選', '台灣'], 'source': '遠見雜誌'}]
可見 organic_results 鍵的值是一個字典串列, 其元素為每一筆搜尋結果, 此處因為指定 num=3, 所以總共有三筆 :
>>> type(results['organic_results'])
<class 'list'>
>>> len(results['organic_results'])
3
串列中的每個字典的鍵與說明如下表所示 :
搜尋結果字典的鍵名 | 說明 |
---|---|
position | 該結果在 Google 搜尋結果中的排名 (位置編號) |
title | 搜尋結果的標題, 通常與網頁標題相符 |
link | 該搜尋結果的網址 (URL) |
redirect_link | 如果有 Google 重定向, 這裡會包含重定向後的 URL |
displayed_link | 在 Google 搜尋結果中顯示的網址 (可能與原始 `link` 不完全相同, 例如省略 `https://` 或 `www.`) |
favicon | 該網站的圖示 (favicon) 圖片 URL |
snippet | 該搜尋結果的簡短摘要, 通常來自該網頁的 `meta description` 或 Google 提取的內容 |
snippet_highlighted_words | 在 `snippet` 中被 Google 強調的關鍵字列表 (可能是搜尋字詞的變體或相關詞) |
source | 如果結果來自特定的新聞來源或平台, 這裡會顯示來源名稱 |
也可以呼叫 results 字典的 get() 方法並傳入 'organic_results', 並指定一個空串列作為預設的回傳值, 迭代回傳之字典串列並透過上表中的鍵名即可取得標題, 摘要, 與網址等 :
>>> for result in results.get('organic_results', []):
print(f'標題: {result["title"]}')
print(f'描述: {result["snippet"]}')
print(f'網址: {result["link"]}\n')
標題: 第16任總統副總統選舉
描述: 第16任總統副總統選舉 ; 金門縣. 柯文哲. /吳欣盈. 賴清德. /蕭美琴. 侯友宜. /趙少康. 1. 2. 3. 13,038. 4,569. 28,005. 28.58%. 10.02%. 61.40% ; 基隆市. 柯文哲. /吳欣盈.
網址: https://db.cec.gov.tw/ElecTable/Election/ElecTickets?dataType=tickets&typeId=ELC&subjectId=P0&legisId=00&themeId=4d83db17c1707e3defae5dc4d4e9c800&dataLevel=C&prvCode=00&cityCode=000&areaCode=00&deptCode=000&liCode=0000
標題: 2024年中華民國總統選舉
描述: 本次是繼2000年後再度未有任一候選人得票率過半的總統選舉,亦是自總統直選以來,首度由同一政黨連續三次獲勝。蔡英文八年執政雖成功交棒,但維持執政地位的民進黨則在同日 ...
網址: https://zh.wikipedia.org/zh-tw/2024%E5%B9%B4%E4%B8%AD%E8%8F%AF%E6%B0%91%E5%9C%8B%E7%B8%BD%E7%B5%B1%E9%81%B8%E8%88%89
標題: 2024 總統大選即時開票
描述: 2024總統大選在即,在賴清德、侯友宜、柯文哲競逐的局勢下,最終誰會拿下總統大位?台灣會迎來新一次的政黨輪替嗎?《遠見》統合各候選人政見,針對選戰熱門關鍵字、候選人 ...
網址: https://event.gvm.com.tw/2024presidential_election/votingresults_president.html
由於通常都是搜尋繁體中文資料, 因此我寫了如下的 search_google() 來簡化 API 的調用 :
>>> def search_google(query, serpapi_key, num=3, gl='tw', hl='zh-tw'):
params={
'q': query,
'api_key': serpapi_key,
'num': num,
'gl': gl,
'hl': hl
}
search=GoogleSearch(params)
results=search.get_dict()
return results.get('organic_results', [])
此函式已預設指定傳回最前面 3 筆繁體中文結果, 呼叫時只要傳入要搜尋的關鍵字 query 與 API Key 即可, 若有搜尋到資料會傳回一個包含 title (標題), snippet (描述), 與 url (網址) 等鍵的字典串列, 若沒有搜尋結果就傳回空字串, 例如 :
>>> results=search_google(query, serpapi_key)
>>> type(results)
<class 'list'>
>>> len(results)
3
>>> type(results[0])
<class 'dict'>
可見傳回了包含 3 筆搜尋結果字典的串列, 用迴圈迭代此串列元素並顯示 title, snippet, 與 url 這三個鍵之值 :
>>> for result in results:
print(f'標題: {result["title"]}')
print(f'描述: {result["snippet"]}')
print(f'網址: {result["link"]}\n')
標題: 2024年中華民國總統選舉
描述: 本次是繼2000年後再度未有任一候選人得票率過半的總統選舉,亦是自總統直選以來,首度由同一政黨連續三次獲勝。蔡英文八年執政雖成功交棒,但維持執政地位的民進黨則在同日 ...
網址: https://zh.wikipedia.org/zh-tw/2024%E5%B9%B4%E4%B8%AD%E8%8F%AF%E6%B0%91%E5%9C%8B%E7%B8%BD%E7%B5%B1%E9%81%B8%E8%88%89
標題: 第16任總統副總統選舉
描述: 第16任總統副總統選舉 ; 金門縣. 柯文哲. /吳欣盈. 賴清德. /蕭美琴. 侯友宜. /趙少康. 1. 2. 3. 13,038. 4,569. 28,005. 28.58%. 10.02%. 61.40% ; 基隆市. 柯文哲. /吳欣盈.
網址: https://db.cec.gov.tw/ElecTable/Election/ElecTickets?dataType=tickets&typeId=ELC&subjectId=P0&legisId=00&themeId=4d83db17c1707e3defae5dc4d4e9c800&dataLevel=C&prvCode=00&cityCode=000&areaCode=00&deptCode=000&liCode=0000
標題: 【Data Reporter】35張圖表,帶你看2024大選關鍵結果
描述: 2024年1月15日 —
網址: https://www.twreporter.org/a/2024-election-results-chart
結果與上面是一樣的.
在 SerpAPI 儀錶板網頁右上角會記錄已呼叫 API 的次數, 免費帳戶每月可呼叫 100 次 :
沒有留言 :
張貼留言