PythonでPinterestのPin (画像)の検索結果を取得する

Pinterest API

この記事のまとめ:
  • PythonでPinterestの検索を行い、その結果の画像のURL等の情報を取得する。
背景:

はじめはInstagram APIを使ってAI (機械学習)用の画像を取得しようと思ったらInstagram APIは審査が非常に厳しくなっているようなので諦めて、代わりにPinterestを使おうと思って色々やってみた記録です。

Pinterest APIでは検索はできない!

Pinterest APIについては、こちらの記事で紹介いたしましたが、Pinterest APIで検索ができるのは自分のアカウントのBoardとPinだけです。

Pinterest APIではすべてのPinを対象にした検索はできないんです。。。

なので作っちゃいました。

サンプルコード

ブラウザでPinterestのページを見に行くと、ログインしないと検索はできませんが、ログインしなくとも検索パラメーターをつけたURLを直接叩くと検索結果を表示ができます。あとは、ブラウザが行っていることをトレースして、同じことをさせただけです。

使い方はカンタン。 search関数に検索ワードと取得したい画像数をいれるだけ!

細かく検証をやっていないので不要なヘッダー情報なども含まれていると思いますが、適宜試されてください。

import os, sys, time
import requests
import json
import bs4 # beautifulSoupe4
 
def search(query, num_pins):
 
    # First access
    url     = 'https://www.pinterest.jp/search/pins/'
    headers = {
        'connection': 'keep-alive'
    }
 
    search_response = requests.get(url, params={'q':query}, headers=headers, stream=False)
    soup            = bs4.BeautifulSoup(search_response.text.replace('\n',''), 'html5lib')
 
    data_json_string = soup.find('script', type='application/json') # extract json string
    data_json        = json.loads(data_json_string.string) # convert into dictionary type variable
    results          = data_json['tree']['children'][0]['data']['results']
#    results          = data_json['resouceDataCache'][0]['children'][0]['data']['results']
 
    image_info_list  = []
    for r in results:
        image_info = {}
        image_info['description'] = r['description']
        image_info['link']        = r['link']
        image_info['image_url']   = r['images']['orig']['url']
        image_info['id']          = r['id']
        image_info_list.append(image_info)
 
 
    # Second or later access to load additional pins that are responded as a JSON string
    url             = 'https://www.pinterest.jp/resource/BaseSearchResource/get/'
    bookmarks       = data_json['resourceDataCache'][0]['resource']['options']['bookmarks']
    experiment_hash = data_json['context']['triggerable_experiments_hash']
    last_cookies    = search_response.cookies
 
    while len(image_info_list) < num_pins:
 
        ## Preparing parameters, headers and cookies for the "get" request
        params = {
            'source_url':'/search/pins/?q={}'.format(query),
            'data':json.dumps({
                'options':{
                    'bookmarks':bookmarks,
                    'query':query,
                    'scope':'pins',
                    'page_size':25,
                    'field_set_key':'unauth_react'
                },
                'context':{}}),
            '_':str(int(time.time())*10*10*10)
        }
 
        headers = {
            'Host':'www.pinterest.jp',
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0',
            'Accept-Language':'ja,en-US;q=0.7,en;q=0.3',
            'X-Pinterest-AppState': 'background',
            'X-Pinterest-ExperimentHash': experiment_hash,
            'X-NEW-APP':'1',
            'X-APP-VERSION':'9b11f84',
            'X-Requested-With':'XMLHttpRequest',
            'Referer':'https://www.pinterest.jp',
            'cookie':json.dumps({
                '_auth':dict(last_cookies)['_auth'],
                'csrftoken':dict(last_cookies)['csrftoken'],
                '_pinterest_sess':dict(last_cookies)['_pinterest_sess']}),
            'connection':'keep-alive'
        }
 
        cookies = {
            '_auth':dict(last_cookies)['_auth'],
            'csrftoken':dict(last_cookies)['csrftoken'],
            '_pinterest_sess':dict(last_cookies)['_pinterest_sess'],
            'bei':'False',
            'logged_out':'True',
            'fba':'True',
            'sessionFunelEventLogged':'1'
        }
 
        search_response = requests.get(url, cookies=cookies, params=params, headers=headers, stream=False)
        data_json       = json.loads(search_response.text)
        results         = data_json['resource_response']['data']['results']
 
        bookmarks       = data_json['resource']['options']['bookmarks']
        experiment_hash = data_json['client_context']['triggerable_experiments_hash']
        last_cookies    = search_response.cookies
 
        for r in results:
            image_info = {}
            image_info['description'] = r['description']
            image_info['link']        = r['link']
            image_info['image_url']   = r['images']['orig']['url']
            image_info['id']          = r['id']
            image_info_list.append(image_info)
 
    return image_info_list
 
 
def main(argv):
    keyword  = 'xxx' # keyword you want to search
    num_pins = 100 # Number of pins searched
 
    image_info_list = search(keyword, num_pins)
 
if __name__ == '__main__':
    main(sys.argv)
 

今回は以上です。 最後まで読んでいただき、ありがとうございます。


ブログランキング・にほんブログ村へ  ← 気に入っていただければ応援ポチをお願いします!

コメント

このブログの人気の投稿

ネットワーク越しの RTL-SDR で SDR# を使う方法

LinuxでのnVidia GPUのオーバークロック・電力チューニング方法