【SalesForce】Pythonでセールスフォースのデータにアクセスする方法

Python

PythonでSalesForceデータにアクセスする方法をまとめました。

もし職場やクライアントがSalesForceを使用しているのであれば、ビジネスに直結するデータがそこにあることとなります。

顧客の特徴分析やセールスの効果測定、訪問→商談→契約までの時系列解析などできることは盛り沢山です!有効に活用していきましょう。

ad

SalesForce接続準備

SalesForce APIのインストール

SalesForceへのアクセスはsimple-salesforceを利用します。
pipを利用してインストールしましょう。

#SalesForceライブラリー
!pip install simple-salesforce
from simple_salesforce import Salesforce

SalesForceアクセスの情報を定義

SalesForceにアクセスするための情報を定義しておきます。
セキュリティーのポリシーは環境ごとに異なるため一概には言えませんが、一例として参考にしてください。
SalesForceのOAuth設定画面よりAPI接続に必要な情報を取得して、接続情報に定義します。

定数名 説明
CLIENT_ID コンシューマ鍵
CLIENT_SECRET コンシューマ秘密鍵
SALESFORCE_ID Sales ForceのユーザーID
SALESFORCE_PW Sales Forceのパスワード
# SalesForceのアクセス情報を定義
URL_AUTH="https://login.salesforce.com/services/oauth2/token"
DATA_PATH="/services/data/v45.0";
# 超センシティブ接続情報
CLIENT_ID='<CLIENT_ID>'
CLIENT_SECRET='<CLIENT_SECRET>'
ID='<SALESFORCE_ID>'
PW='<SALESFORCE_PW>'

SalesForceAPIの接続

OAuth認証

OAuth認証を経由してアクセストークンを取得してRestサービスに接続するためのセッション情報を取得します。

import json
import requests

#SalesForceへのセッション情報を取得
headers={'content-type':'application/x-www-form-urlencoded'}
payload={
    "grant_type": "password",
    "client_id": CLIENT_ID,
    "client_secret": CLIENT_SECRET,
    "username": ID,
    "password": PW
}
res=requests.post(URL_AUTH,headers=headers,data=payload)

# 実行結果を判定
if res.status_code!=200:
    raise Exception(f'code:{res.status_code}, text:{res.text}')

# 実行結果の取得
session=requests.Session()
res_info=json.loads(res.text)
instance_url=res_info['instance_url']
,access_token=res_info['access_token']

SalesForceオブジェクトを作成

OAuth認証で取得した値を使用してSalesforceオブジェクトを作成してSalesForceデータへアクセスを行います。

# Salesforceオブジェクトの取得
sf=Salesforce(
    instance_url=instance_url
    ,session_id=access_token
    ,session=session
)

SOQLの定義と実行

Salesforceのquery_all_iter()関数を利用してSalesForceよりデータを取得します。
その際のスキーマ言語としてSOQLというSQLライクなSELECT文を使用します。

SOQLは癖が強くSQL的に使えはするのですが、痒いところに手が届かず。といった印象です。試行錯誤すると思いますが、SalesForceの開発者コンソールなどを利用してもろもろ試してみてください。

# SOQLの定義
soql='''\
SELECT id
    ,AccountId
    ,Name
    ,LastName
    ,MailingAddress
    ,MailingState
    ,MailingPostalCode
    ,Phone
    ,Email
    ,Department
FROM Contact
LIMIT 3
'''
# SOQL分の整形
soql=soql.replace('\n',' ').replace('\t',' ').replace('   ',' ').replace('  ',' ')

# 実行前のデータを取得
result=sf.query_all_iter(soql)

query_all_iter()直前のreplace()関数は蛇足ではありますが、SQOL文には文字制限(HTTP-GET制限)があるためミニマム化しています。
今回は短いSOQL分なので必要ないのですが、query_all_iter()を実行する際には必ず処理するようにしています。

SalesForceデータをデータフレームに格納

SOQLの結果がJSON形式で取得されるため、必要なデータのみをDIC型の配列としてデータを格納して最後にデータフレームとして保存します。

ここではcolumns配列に項目名を定義してデータフレームでのカラム名と定義しています。

import pandas as pd

rows=[]
columns=[]
# SalesForceデータをGCSにCSVとして保存
for result_row in result:
    # ヘッダーの作成
    if not columns :
        columns=list(result_row.keys())
        columns.remove('attributes')
    #レコードを分割してカラムデータを取得
    row=[]
    for key, val in result_row.items():
        # 不要なデータはスキップ
        if key=='attributes': continue
        # 値が文字列の場合、諸々のコンバート処理を行う
        if type(val) is str:
            # CSV処理を行う場合を考慮してメタ文字類を置換する
            val=val.replace('"', '”').replace("'", "’").replace(',', '、').replace('\n', '\n')
            # 日付データが特殊なため"yyyy-mm-dd hh:MM:ss"形式に置換する
            if '.000+0000' in val and 'T' in val :
                val=val.replace('.000+0000','').replace('T',' ')
        # カラムデータ追加
        row.append(val)
    # レコードデータ追加
    rows.append(row)

# DOC型の配列をデータフレームに格納する
df=pd.DataFrame(rows, columns=columns)

データの値をDOCオブジェクトに取得する際には後続の処理(CSV処理やスプレッドシート保存など)を考慮してメタ文字の置換を行なっていますが、こちらの処理はケースバイケースとなります。用途に合わせて実装してみてください。

また、DateTime型は後続処理でトラブルとなることが多いのでこのタイミングで置換することが多いです。

コメント