請啟用JavaScript來查看內容

DataForSEO 教學 — Google、Yahoo 搜尋結果 SERP API

    (先澄清,以下非業配,純粹依個人使用過程描述。)

    前言

    在很久之前,我有寫一篇關於第三方 Google 搜尋結果的 API (Aves API)。而最近又在因緣際會下,被迫(?)接觸了另一個類似的服務平台 — DataForSEO。

    DataForSEO 提供了更多的服務,包括 Google Search、Google Maps、Google News、Google Images、YouTube、Yahoo Search、Bing Search、百度 Search、Google Play 和 Apple App,還有一些其他商業應用的服務。可以看的出來還蠻多樣的,如果有這方面的需求或許可以參考。

    這次就改以「Yahoo 搜尋 API」當範例,來跟著我一起嘗試這個 API 服務吧,這篇也算把我自己的使用經驗記錄下來。


    DataForSEO 官網
    DataForSEO 官網

    SERP API

    官方的 SERP API 頁面 有一些簡單的介紹,SERP API 目前支援以下幾種搜尋:

    • Google SERP
    • Google 圖片
    • Google 新聞
    • Google 地圖
    • Yahoo SERP
    • Bing SERP
    • 百度 SERP
    • YouTube SERP
    SERP API 支援的搜尋引擎
    SERP API 支援的搜尋引擎

    搜尋測試頁面

    在 DataForSEO 官網上有提供一個 Google SERP 搜尋測試頁面,可以實際輸入關鍵字,並查看它回傳的資料,只可惜好像沒有提供台灣的選項。

    但它在使用者後台(需註冊)也有提供一個 API Explorer (就是 Playground) 的 GUI 介面,會完整許多,各種支援的搜尋引擎都可以選,地區也有台灣(並細分到縣市),也有許多參數可以設定,但這邊就會直接花到錢的 (新帳戶有送 1 美元的額度可供試用)。

    關於使用者後台頁面,我文章後續章節會再介紹。

    Google SERP 搜尋測試頁面
    Google SERP 搜尋測試頁面

    SERP API 價格

    搜尋 API 價格官方有詳細說明在這個網頁,依照你使用的模式它分為三種價格:STANDARD QUEUE、PRIORITY QUEUE、LIVE MODE。

    • STANDARD QUEUE:每一次查詢 $0.0006,平均等 5 分鐘。
    • PRIORITY QUEUE:每一次查詢 $0.0012,平均等 1 分鐘。
    • LIVE MODE:每一次查詢 $0.002,平均等 6 秒。

    * 以上價格為美金

    SERP API 價格
    SERP API 價格

    LIVE MODE 使用上最簡單,只要單一請求就會回傳結果,速度也最快,但價格當然也最貴。
    STANDARD QUEUE 和 PRIORITY QUEUE 則是要先發送查詢任務請求,再來定時去問問它查好了沒,最後再取得查詢結果,要分成三段,在程式上寫起來比較麻煩,但它比較便宜(窮人的悲哀QQ),而 STANDARD QUEUE 和 PRIORITY QUEUE 兩者看起來只差在等待時間及價格。


    以下文章我會以 STANDARD QUEUE 和 PRIORITY QUEUE 模式來示範。


    API 使用

    SERP API 使用上分為三個請求:

    1. Task POST (task_post):設定任務
    2. Tasks Ready (tasks_ready):取得已完成任務
    3. Task GET (task_get):取得任務的結果

    * STANDARD QUEUE、PRIORITY QUEUE 模式的區分是在送出 task_post 請求時,帶上 priority 參數來指定,1 (預設)代表 STANDARD、2 代表 PRIORITY。


    SERP API 流程
    SERP API 流程
    1. 首先使用 "Task POST" 設定查詢任務,指定關鍵字以及其餘參數,讓它開始去抓我們想要的搜尋結果,這邊最多可以一次給 100 組關鍵字,不過稍微注意有限制每分鐘最多只能發送 2000 個 API 請求。

      * 你也可以指定 pingback_url,當任務完成時它會主動通知你;
      * 或指定 postback_url,當任務完成時它會主動將結果傳送給你。

    2. 再來使用 "Tasks Ready" 查詢它執行完哪些任務,可以每 10 秒檢查一次,或一分鐘檢查一次,它只有限制每分鐘最多進行 20 次 API 請求。另外,已經被收集的任務(我猜是指已使用 task_get 取得的任務)和放超過三天未收集的任務會被移除不會在裡面。

    3. 最後,使用 "Task GET" 帶上任務 ID 取得任務的查詢結果,它有分三種 Regular、Advanced、HTML,Regular 就是以 JSON 格式整理好的結果;Advanced 跟 Regular 一樣,只是好像還有多一些特定資訊,我也不是很清楚;HTML 就是回傳搜尋結果的 HTML 格式。

      * 而且任務結果在 30 天內都會保留,用 ID 都可以取得結果。
      * 關於搜尋結果不同類別(type)各自代表甚麼,在這邊有官方的圖文說明:https://dataforseo.com/serp-features

    * 以上三種請求,只有 "Task POST" 會收費,其餘兩個並不會產生費用。



    送出的請求 Header 皆需要帶上憑證,確認是哪個帳號發出的,其格式如下:

    Authorization: Basic ${credentials}
    

    其中 credentials 是將你的 "API login" 與 "API password" 組的字串 {login}:{password} 經過 Base64 編碼的結果。

    例如帳號是 jia@gmail.com、密碼是 abc123,組成 jia@gmail.com:abc123,再經過 Base64 變成 amlhQGdtYWlsLmNvbTphYmMxMjM=

    * "API login" 與 "API password" 可以在 使用者後台 API Dashboard 網頁找到。



    對了,
    它們 API 還有提供 📦 沙盒模式(Sandbox),讓我們可以在撰寫程式時做測試,不會花費到費用,但當然回傳的資料就是它們的範例資料,但可以讓我們確認 API 回傳的資料格式、測試程式有沒有問題。

    官方文件:https://docs.dataforseo.com/v3/appendix/sandbox/



    * 官方文件有更完整的說明:https://docs.dataforseo.com/v3/serp/yahoo/overview/

    * 其他常見的 Q&A:https://dataforseo.com/help-center/category/serp-api


    Python 範例

    首先要確認有安裝 Requests 套件:

    1
    
    pip install requests
    

    完整 Python 程式碼:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    
    import json
    import requests
    
    
    class DataforseoSerp():
    
        def __init__(self, credentials, open_sandbox=False):
            self.base_url = 'https://api.dataforseo.com/v3/serp'
            if open_sandbox:
                self.base_url = 'https://sandbox.dataforseo.com/v3/serp'  # 沙盒模式
            self.search_engine = 'yahoo'
            self.headers = {
                'Authorization': f'Basic ${credentials}',
                'Content-Type': 'application/json',
            }
            self.location_code = 1012825  # New Taipei City,Taiwan
            # https://docs.dataforseo.com/v3/serp/yahoo/locations/
            self.language_code = 'zh-TW'
            # https://docs.dataforseo.com/v3/serp/yahoo/languages/
            self.device = "desktop"  # mobile
            self.os = "windows"  # macos android ios
    
        def task_post(self, keywords, depth=100):
            """
            設定查詢任務,keywords 最多一次可以 100 個,每分鐘最多可以發送 2000 個 API 呼叫
            https://docs.dataforseo.com/v3/serp/yahoo/organic/task_post/
            """
            if (keywords is None) or (len(keywords) == 0):
                return None
    
            url = f'{self.base_url}/{self.search_engine}/organic/task_post'
            data = []
            for keyword in keywords:
                data.append({
                    "keyword": keyword,
                    "location_code": self.location_code,
                    "language_code": self.language_code,
                    "device": self.device,
                    "os": self.os,
                    "depth": depth
                })
            
            response = requests.post(url, headers=self.headers, json=data)
            return response.json()
    
        def tasks_ready(self):
            """
            取得已完成的查詢任務
            https://docs.dataforseo.com/v3/serp/yahoo/organic/tasks_ready/
            """
            url = f'{self.base_url}/{self.search_engine}/organic/tasks_ready'
            response = requests.get(url, headers=self.headers)
            return response.json()
    
        def task_get(self, task_id):
            """
            取得查詢任務的結果
            https://docs.dataforseo.com/v3/serp/yahoo/organic/task_get/regular/
            """
            if task_id is None:
                return None
            url = f'{self.base_url}/{self.search_engine}/organic/task_get/regular/{task_id}'
            response = requests.get(url, headers=self.headers)
            return response.json()
    
    
    if __name__ == "__main__":
        dataforseo_serp = DataforseoSerp("xxxxxxxxxxxxxxxxxxxxxxxxxxx", open_sandbox=True)
        
        result = dataforseo_serp.task_post(["飲料"])
        print(json.dumps(result))
        
        result = dataforseo_serp.tasks_ready()
        print(json.dumps(result))
        
        result = dataforseo_serp.task_get("11171539-6790-0066-2000-fa82270464a2")
        print(json.dumps(result))
        with open('dataforseo_serp_result.json', 'w') as f:
            json.dump(result, f)
    

    當然比較好的做法,是還要判斷它回傳結果的 status_code 欄位和 tasks 底下的 status_code 欄位,確保任務執行 OK 才去取資料,如果有錯誤,程式內要做相對應處理。

    這邊只是為了示範,我就沒有寫出來了。

    * 各個狀態代碼意思如這個官方清單


    使用者後台

    當註冊後登入,即可進入 使用者後台頁面 去查看更多相關資訊。

    其中有幾個重要的頁面:

    • API Dashboard (儀錶板)
    • API Usage (使用紀錄)
    • API Errors (錯誤紀錄)
    • API Explorer (API Playground)
    • API Settings (設定 API 限制)

    API Dashboard (儀錶板)

    有顯示你的 "API login" 與 "API password",以及圖表化顯示每天的花費。

    API Dashboard (儀錶板) 頁面
    API Dashboard (儀錶板) 頁面

    API Usage (使用紀錄)

    就是你 API 的呼叫紀錄,它有將不同種類的 API 區分開來,方便我們查找。
    有紀錄任務 ID、執行時間、執行狀態、花費、送出的參數,甚至可以從這邊看到查詢結果(等同於 "Task GET" 請求)。

    API Usage (使用紀錄) 頁面
    API Usage (使用紀錄) 頁面

    API Errors (錯誤紀錄)

    發生錯誤的 API 請求會在這頁列出來。

    API Errors (錯誤紀錄) 頁面
    API Errors (錯誤紀錄) 頁面

    API Explorer (API Playground)

    以圖形化的操作頁面,讓你實際測試 API 的結果是否符合你的預期,有輸入框讓你設定 API 不同參數,像是用哪個搜尋引擎、地區(有細分到縣市)、語言、電腦版或手機版、作業系統、關鍵字。

    但要稍微注意,這邊是會直接花到錢的 (新帳戶有送 1 美元的額度可供試用)。

    API Explorer (API Playground) 頁面
    API Explorer (API Playground) 頁面

    API Settings (設定 API 限制)

    能設定可以呼叫 API 的 IP 白名單、限制每日最大花費額度(總共額度,或也可以細到 by 不同 API 去限制)。

    API Settings (設定 API 限制) 頁面
    API Settings (設定 API 限制) 頁面

    注意事項

    我在使用 Yahoo 搜尋 API 時發現,我明明設定要 100 筆結果(depth=100),結果回傳只有 70 筆、甚至 40 幾筆而已的,我也有透過 API 回傳的 check_url 網址去確認,經過詢問與確認,官方是這樣答覆我:

    Today, you contacted our Support Team and provided us with ID of your task sent to the Yahoo Serp API that returned fewer results than expected.
    Our developers have carefully checked the situation and explained that such a search engine has some limitations. To avoid timeouts, we have a restriction that allows us to crawl up to 6 pages of the ordinary SERP (the one you can see in a browser). Taking into account that each page contains 7-8 results. In total, the API does not return more than 50 results.
    If we remove such a restriction globally, this API will return 500 errors, and since we will have to send numerous requests to this search engine, it may harm it due to high traffic coming from us. I hope it makes sense.
    Hope for your understanding!

    也就是可能他們的 Yahoo 搜尋 API 很可能沒辦法抓到我們指定的筆數,除非你只需要第一頁,或前三頁之類的,不然這也是很困擾,要特別注意。


    結語

    相比上次使用的 Aves API 來說,DataForSEO 真的多了非常多的服務,而且價格貌似也比較便宜。官方同樣有線上客服,有相關需求都可以直接詢問,回應速度還蠻快的。

    當然我目前只是短暫的嘗試,還不確定它長久、大量地使用下來穩定性如何,這部分有需求的人可以自行比較看看。




    參考:
    DataForSEO 官方網站
    DataForSEO 官方文檔
    DataForSEO Dashboard 後台


    「失敗很正常,如果沒有經歷失敗,表示你還不夠創新。」
    Failure is an option here. If things are not failing, you are not innovating enough.

    —— Elon Musk 伊隆·馬斯克 (著名企業家)


    🔻 如果覺得喜歡,歡迎在下方獎勵我 5 個讚~
    分享

    Jia
    作者
    Jia
    軟體工程師