発達障害考察ブログ HyogoKurumi.Scribble

言葉は嘘をつきません

【PA-API】複数ASINの商品情報(ランキング、中古価格、商品リンクURL、他)をASIN一覧リストから一気に取得するコード【Python】

スポンサーリンク

 実は数年間ほど、副業の関係でAmazonアソシエイトプログラムのProductAdvertisingAPIサービスを利用していたのですが、副業の閉業や生活環境の変化に伴い、自分は引退となりました。そこで現役時代に使用していた半自作の、PA−API用のPythonコードを公開しようと思います。

 

 

概要

  • 本コードは大量のASINの商品情報を一気に取得したい人向けのコードです。
  • 商品情報を取得したいASINのリストを、専用のPyファイルに貼り付けなどで入力し、本体のPyコードを実行すると、取得した商品情報がテキストファイルに書き出されます。
  • 取得できる情報は商品タイトル、ASIN、ランキング、新品出店者数、中古出店者数、マケプレ中古最低価格、商品リンクURL(DetailPageURL)です。
  • エラー発生時にメールで通知&連続発生で自動停止する機能付きです。
  • コードの一部にはGoogle検索で辿り着いたサイト様のコピペの他、コーディング系Q&Aサイトの力を借りています。
  • 本コードは勉強中の身で作成したものであり、部分的には最適・最良ではありません。コピペ等で利用される方は自己責任でご使用ください。

 

導入について

  1. 適当な作業フォルダの中に本記事掲載の「search_amazon.py」「list_amazon.py」を作成してください。加えて同じフォルダの中に「_errormailcode」という名前のフォルダを作成してください。
  2. フォルダ「_errormailcode」の中に「mailamazonapi_out.py」を作成してください。
  3. 掲載コードの赤文字部分を自分の情報に書き換えてください。ACCESS_KEY等はご自身のアカウント情報で。メールはGmailのみ対応してます。
  4. 「list_amazon.py」に商品情報を取得したいASINを「'XXXXXXXXXX',」という形式で、縦一列に入力してください。ASINが「'」と「',」に挟まれていればOKです。掲載しているコードにはテスト用にドラゴンボールコミックのASINが入力してあります。3点だけですが、100点でも1000点でもASINを並べれば取得できます。

 

免責事項

本コードを利用したことにより、いかなる不具合、不都合、損害が生じた場合についても、私「来未炳吾」は一切の責任を負いません。サポートも致しません。カスタマイズの方法は全てご自身で調べ、全て自己責任にてご利用ください。

 

ディレクトリ

メインフォルダ内(フォルダ名は任意)

  • search_amazon.py
  • list_amazon.py
  • _errormailcode(フォルダ)

_errormailcodeフォルダ内

  • mailamazonapi_out.py

 

search_amazon.py

import codecs
import bottlenose
import time
import sys
from bs4 import BeautifulSoup
from urllib.request import urlopen
from urllib.error import URLError, HTTPError
import list_amazon

ACCESS_KEY = "XXXXXXXXXXXXXXXXXX"
SECRET_ACCESS_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ASSOCIATE_TAG = "XXXXXX-22"

amazon = bottlenose.Amazon(ACCESS_KEY, SECRET_ACCESS_KEY, ASSOCIATE_TAG, Region="JP")

def main(f):
    for isbn in list_amazon.isbn:

        for _ in range(5):
            try:
                response = amazon.ItemLookup(ItemId=isbn, ResponseGroup="Large", SearchIndex="Books", IdType="ISBN")
                soup = BeautifulSoup(response, "html.parser")

                print(soup.title.getText())
                title = soup.title.getText()

                print(soup.asin.getText())
                asin = soup.asin.getText()
                
                print(soup.salesrank.getText())
                salesrank = soup.salesrank.getText()
                
                print(soup.totalnew.getText())
                totalnew = soup.totalnew.getText()
                
                print(soup.totalused.getText())
                totalused = soup.totalused.getText()
                
                print(soup.formattedprice.getText())
                formattedprice = soup.formattedprice.getText()
                
                print(soup.detailpageurl.getText())
                detailpageurl = soup.detailpageurl.getText()

                with open("result_amazon.txt", "a", encoding="utf-8") as f:
                    f.write(title)
                    f.write("|")
                    f.write(asin)
                    f.write("|")
                    f.write(salesrank)
                    f.write("|")
                    f.write(totalnew)
                    f.write("|")
                    f.write(totalused)
                    f.write("|")
                    f.write(formattedprice)
                    f.write("|")
                    f.write(detailpageurl)
                    f.write("\n")

                time.sleep(10)
                
                title = "none"
                asin = "none"
                salesrank = "none"
                totalnew = "none"
                totalused = "none"
                formattedprice = "none"
                detailpageurl = "none"
                
                time.sleep(1)
                                
                break
                
            except AttributeError :
                print("AttributeError!")
                time.sleep(3)
                break
        
            except:
                print("謎のエラー発生!")
                from _errormailcode import mailamazonapi_out
                import traceback
                traceback.print_exc()
                exit()

        else:
            print("エラー5回終了!")
            from _errormailcode import mailamazonapi_out
            time.sleep(1)
            exit()            
    
if __name__ == '__main__':
        main("")

 

list_amazon.py

isbn=[
'4088518314',
'4088734440',
'4088806611',
]

 

mailamazonapi_out.py

from email import message
import smtplib

smtp_host = 'smtp.gmail.com'
smtp_port = 587
from_email = 'XXXXXXXXXX@gmail.com' # 送信元のアドレス
to_email = 'YYYYYYYYYY@gmail.com' # 送りたい先のアドレス
username = 'XXXXXXXXXX@gmail.com' # Gmailのアドレス
password = 'PPPPPPPPPP' # Gmailのパスワード

# メールの内容を作成
msg = message.EmailMessage()
msg.set_content('エラー発生') # メールの本文
msg['Subject'] = 'エラー発生通知(amazonapi)' # 件名
msg['From'] = from_email # メール送信元
msg['To'] = to_email #メール送信先

# メールサーバーへアクセス
server = smtplib.SMTP(smtp_host, smtp_port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(username, password)
server.send_message(msg)
server.quit()
 

 

制作経緯と公開ついて

 最初はどこかのサイトで拾ったExcelVBAのコードで商品情報を取得していたのですが、後に、そのコードは1商品1リクエストではなく取得した情報1項目毎にリクエストするというサーバーに大変負担をかけやすいコードであることを知り、それをきっかけに自作コードに挑戦しました。(例:A商品からタイトルと価格とランキング抜いて3リクエスト(^^;))

 私は上記コードでiosのPythonistaで使用していました。本コードなら、1商品から複数の項目を書き出しますが、1商品1リクエストになっていると認識しています。

 あと本プログラムの目的とその性質上、一度実行させたら後は放置で別作業という運用になりやすいわけですが、万一にも向こうのサーバーに負担をかけないよう、何かしらエラーが発生したらメールで通知の上、同じASINに再度リクエストし、それでも5回連続エラーが出たら動作を停止するようになっています。ただし「AttributeError」のみ停止せず、そのASINは飛ばして次のASINを取得します。

 プログラムはPython以前に全くのコーディング初心者なので、最適化できる記述が多々あるかと思います。書き換えできる人はぜひそうしてください。

 尚、自分はビビリなので無駄にtime.sleep(10)とかにしています。匙加減がわかる方はお好きなように変えてください。(詳しくない方へ:time.sleepの値を絶対に0にしないでください)

 

参考サイト様