カバー画像の取得コードを改良

商品画像のimg要素のHTML構成は、書籍、電子書籍、などの場合のパターンが多く、前バージョンでは「No image」になる場合が時々ありました。 商品ページのフォーマットが統一されていれば対応は簡単ですが、この種のツールとしては Amazonの実情に合わせるしかありません。

 

今回、幾つかのHTMLパターンに絞り込んた「要素セレクタ」を、順に試すというコードを導入して、商品画像を確実に取得できる様にしました。

 

「Amazon Item_URL」ver.0.5    220行~

let item_img; // 商品画像
let item_img_src; // 商品画像のSRC
let sam_selector=[
    '#main-image-container li.selected img',
    '#ebooks-img-wrapper img',
    '#imageBlockCommon img',
    '#leftCol img']; // 考えられる商品画像のセレクタの配列
for(let k=0; k<sam_selector.length; k++){
    item_img=document.querySelector(sam_selector[k]);
    if(item_img){
        item_img_src=item_img.getAttribute('src');
        break; }}

if(!item_img_src){ // 商品画像が取得出来ない時「No-image」の代替画像を表示
    item_img_src=
        "https://m.media-amazon.com/images/I/01RmK+J4pJL._AC_UL150_.gif"; }

 

この部分で、商品画像を取得してSRCを得ます。

今回工夫をしたのは、商品画像を指定するセレクタを4種を配列にした事です。 この配列には、他にも新しいセレクタのパターンが見つかれば、追加できます。

 

その後のコードは、この配列の先頭から順番にセレクタを試して、サムネイル画像を取得出来るかどうかを試すコードです。 もし、セレクタに対応する商品画像があれば、そこでループは終了し、その商品画像のSRCを次に送ります。

 

配列をもっとスマートにテストするコードがあると思いますが、この程度ではスピード差も出ないので、判り易いベタなコードとしました。

 

このコードの採用で、電子書籍などの商品画像が確実に取得できる様になりました。

 

 

 

 電子書籍の価格の取得

書籍関連の価格表示は、通常の商品ページとHTML構成が異なります。 前バージョンでは、書籍価格を取得対象にしていませんでしたが、今回は、電子書籍の価格だけは取得する様にしました。 取得先は、下の赤枠の部分です。 書籍で他の所(紙の版など)に価格表示があっても、対象になりません。

 

 

 

 

カードのレイアウトの変更 とファビコンの導入

下は、新しいレイアウトのサンプルです。

 

 

上のサンプルもそうですが、「商品タイトル」が長くて2行に収まらない場合、その後に付け加えた「商品価格」が完全に隠れます。 また、商品価格が取得出来ない場合は、タイトル部に大きく代替文字の「商品価格」が表示され、修正をしない場合は大変に違和感がありました。

 

これらの不都合を考慮して、上図の様に「商品価格」を「商品の説明」の先頭に移動しました。 ここなら隠れる心配はなく、また「商品価格」が取得出来ない場合も、大きくは表示されずに適切です。 また、代替文字は「Amazon価格」の文字に変更しました。

 

前バージョンはリンクカードのデフォルトのリンクアイコンを使っていましたが、このツールは「Amazon専用」なので、Amazonの「ファビコン」に変更しました。

 

 

 

 

 Text ⇄ Card の選択を明瞭化

前バージョンでは、Amazon内の商品ページを移動すると、「Text ⇄ Card」の選択がデフォルトの「Text」に戻ってしまいました。 このツールを起動してカード生成が1回で終わる場合は無問題ですが、時には複数のカードを生成する場合もあります。 そういう時に、毎回「Card」に切り換える必要があるのは不便です。

 

そこで、ローカルストレージでユーザーの選択を保持して、ツール起動の度に選択が再現する様しました。 また、テストをしていて、選択が「Card」と思ってペースト操作後に「Text」のままという事が良くありました。 スイッチデザインで区別をより視覚化すれば間違いは減らせると考えて、下の様に「Card」の場合のスイッチの色を「黄色」に改めました。

 

 

 

 

 リンクカードの生成とHTML貼付けの方法

「Amazon Item_URL」で商品のリンクカードを作る方法は、前ページに整理していますので参照ください。

 

 

 

 

リンクカードを扱う上での関連ツール 

 

LinkCard Editor」を使うと、カード上の文字の修正、独自のカバー画像、配色のカスタマイズなど、より見栄えの良いカードに編集ができます。

 

 

Both-WH」は「通常表示」のキャレット位置から、「HTML表示」の同じ位置へのジャンプを可能にします。「通常表示」でカードの貼り付け位置にキャレットを入れて「Ctrl+F8」を押すと、「HTML編集画面」の貼付け位置にキャレットが移動するので、そこでペーストをするだけです。 HTML編集操作一気に簡単になります。

 

 

 

 

「Amazon Item_URL」を利用するには

このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。  以下に、このツールの導入手順を簡単に説明します。

 

❶「Tampermonkey」を導入します

◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。

既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。 

拡張機能の導入については、以下のページに簡単な説明があるので参照ください。

 

 

❷「Tampermonkey」にスクリプトを登録します

◎「Tampermonkey」の「」マークの「新規スクリプト」タブを開きます。

 

 

 

◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。

 

 

〔 Amazon Item_URL 〕 ver. 0.5

 

// ==UserScript==
// @name         Amazon Item_URL
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  アマゾンの商品ページのURLを短縮
// @author       You
// @match        https://www.amazon.co.jp/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=amazon.co.jp
// @grant        none
// ==/UserScript==


let panel_disp=0; // パネルの表示フラグ
let action=0; // Textリンク Cardリンク の選択フラグ

action=localStorage.getItem('AIURL_Link_action');
if(!action){
    action=0; // Textリンクが初期値
    localStorage.setItem('AIURL_Link_action', action); } // 🔵ストレージ記入



let retry=0;
let interval=setInterval(wait_target, 20);
function wait_target(){
    retry++;
    if(retry>20){ // リトライ制限 20回 0.4secまで
        clearInterval(interval); }
    let target=document.body; // 監視 target
    if(target){
        clearInterval(interval);
        env(); }}


function env(){

    let panel=
        '<div id="tr_panel">'+
        '<div id="tr_url"></div>'+
        '<button id="tr_test" class="color_sw">Test</button>'+
        '<button id="tr_select" class="color_sw">'+
        '<span class="t1">Text</span> <span class="t2">Card</span></button>'+
        '<button id="tr_copy" class="color_sw">Copy</button>'+
        '<button id="tr_close" class="color_sw">✖</button>'+
        '</div>'+
        '<style>#tr_panel { position: fixed; top: 0px; left: 0; z-index: 5000; '+
        'font: normal 16px/24px Meiryo; padding: 14px 20px 12px; '+
        'background: #fff; border: 1px solid #aaa; align-items: center; display: none; } '+
        '#tr_url { padding: 4px 15px 2px; border: 1px solid #aaa; '+
        'max-width: 80vw; word-break: break-word;} '+
        '#tr_select { width: 90px; } '+
        '#tr_panel .t1 { opacity: 1; font-size: 16px; } '+
        '#tr_panel .t2 { opacity: .3; font-size: 12px; } '+
        '#tr_panel.card .t1 { opacity: .3; font-size: 12px; } '+
        '#tr_panel.card .t2 { opacity: 1; font-size: 16px; } '+
        '#tr_panel .color_sw { margin-left: 15px; padding: 2px 10px 0; height: 32px; '+
        'border: 1px solid #aaa; background: linear-gradient(transparent, #c3e0ee); } '+
        '#tr_panel .color_sw:hover { background: linear-gradient(#c3e0ee, transparent); } '+
        '#tr_panel.card .color_sw { background: linear-gradient(transparent, #ffe082); } '+
        '#tr_panel.card .color_sw:hover { background: linear-gradient(#ffe082, transparent); } '+
        '</style>';

    if(!document.querySelector('#tr_panel')){
        document.body.insertAdjacentHTML('beforeend', panel); }}



let target=document.head; // 監視 target
let monitor=new MutationObserver(item_page);
monitor.observe(target, {childList: true}); // 監視開始

function item_page(){
    let nav_a=document.querySelector('#nav-logo a');
    if(nav_a){
        nav_a.style.outline="2px solid red"; }

    let nav=document.querySelector('#nav-logo');
    if(nav){
        nav.onclick=function(event){
            if(!event.ctrlKey && !event.shiftKey){
                event.preventDefault();
                tr_short(); }}}}



function tr_short(){
    let tr_panel=document.querySelector('#tr_panel');
    if(tr_panel){
        if(panel_disp==0){
            panel_disp=1;
            tr_panel.style.display='flex';
            main(); }
        else{
            panel_disp=0;
            tr_panel.style.display='none'; }}}



function main(){
    let url_input=document.querySelector('#tr_url');
    if(url_input){
        let def_url=location.href;
        let smart_url;
        let product;

        if(def_url.indexOf('www.amazon.co')==-1){ // Amazon以外
            smart_url=cut_after(def_url, '?'); }
        else{ // Amazonの場合
            if(def_url.indexOf('/b/')==-1 && def_url.indexOf('/b?')==-1 &&
               def_url.indexOf('/s/')==-1 && def_url.indexOf('/s?')==-1 &&
               cut_before(def_url, '?').indexOf('node=')==-1){
                if(def_url.indexOf('/gp/')!=-1){
                    product=cut_after(cut_before(cut_after(def_url, '?'), '/gp/'), '/ref=');
                    smart_url='https://www.amazon.co.jp'+ product; }
                else if(def_url.indexOf('/dp/')!=-1){
                    product=cut_after(cut_before(cut_after(def_url, '?'), '/dp/'), '/ref=');
                    smart_url='https://www.amazon.co.jp'+ product; }
                else{
                    smart_url=cut_after(def_url, '?'); }}
            else{
                smart_url=def_url; }}

        url_input.textContent=smart_url;

        act_limit();
        test();
        select_act();
        copy();
        close(); }



    function cut_before(row, string){ // 前方を削除
        let rs;
        if(row.indexOf(string)!=-1){
            rs=row.substring(row.indexOf(string));
            return rs; }
        else{
            return row; }}

    function cut_after(row, string){ // 以降を削除
        let rs;
        if(row.indexOf(string)!=-1){
            rs=row.substring(0, row.indexOf(string));
            return rs; }
        else{
            return row; }}



    function act_limit(){
        let productTitle=document.querySelector('#productTitle');
        if(!productTitle){
            let tr_select=document.querySelector('#tr_select');
            if(tr_select){
                tr_select.style.display='none'; }}}



    function test(){
        let tr_test=document.querySelector('#tr_test');
        if(tr_test){
            tr_test.onclick=function(){
                if(panel_disp==1){
                    let url_input=document.querySelector('#tr_url');
                    if(url_input.textContent){
                        window.open(url_input.textContent, '_blank'); }}}}}



    function select_act(){
        let tr_panel=document.querySelector('#tr_panel');
        let tr_select=document.querySelector('#tr_select');
        if(tr_panel && tr_select){
            sel_disp();

            tr_select.onclick=function(){
                if(action==0){
                    action=1;
                    tr_panel.classList.add('card');
                    localStorage.setItem('AIURL_Link_action', action); // 🔵ストレージ記入
                    sel_disp(); }
                else{
                    action=0;
                    tr_panel.classList.remove('card');
                    localStorage.setItem('AIURL_Link_action', action); // 🔵ストレージ記入
                    sel_disp(); }}

            function sel_disp(){
                if(action==0){
                    tr_panel.classList.remove('card'); }
                else{
                    tr_panel.classList.add('card'); }}}}



    function creat_card(){
        let item_title='Amazon 商品 タイトル';
        let productTitle=document.querySelector('#productTitle');
        if(productTitle){
            item_title=productTitle.textContent; }

        let item_price='Amazon価格';
        let PriceDisplay=document.querySelector('#corePriceDisplay_desktop_feature_div .a-offscreen');
        if(PriceDisplay){
            item_price=PriceDisplay.textContent; }
        else{
            PriceDisplay=document.querySelector('#tmmSwatches .a-button-inner');
            if(PriceDisplay){
                item_price=PriceDisplay.textContent; }}

        let item_overview='商品説明';
        let productOverview=document.querySelector('#productOverview_feature_div table');
        if(productOverview){
            item_overview=productOverview.textContent;
            if(item_overview.length>400){
                item_overview=item_overview.substr(0, 400); }}

        let item_img;
        let item_img_src;
        let sam_selector=[
            '#main-image-container li.selected img',
            '#ebooks-img-wrapper img',
            '#imageBlockCommon img',
            '#leftCol img'];
        for(let k=0; k<sam_selector.length; k++){
            item_img=document.querySelector(sam_selector[k]);
            if(item_img){
                item_img_src=item_img.getAttribute('src');
                break; }}

        if(!item_img_src){
            item_img_src=
                "https://m.media-amazon.com/images/I/01RmK+J4pJL._AC_UL150_.gif"; }


        let card_tx=
            '<div class="ogpCard_root">'+
            '<article class="ogpCard_wrap" '+
            'contenteditable="false" style="display:inline-block;max-width:100%">'+
            '<a class="ogpCard_link" data-ogp-card-log="" href="'+ url_input.textContent +
            '" rel="noopener noreferrer" style="display:flex;justify-content:space-between;'+
            'overflow:hidden;box-sizing:border-box;width:620px;max-width:100%;'+
            'height:120px;border:1px solid #e2e2e2;border-radius:4px;background-color:#fff;'+
            'text-decoration:none" target="_blank">'+
            '<span class="ogpCard_content" style="display:flex;flex-direction:column;'+
            'overflow:hidden;width:100%;padding:16px">'+
            '<span class="ogpCard_title" style="-webkit-box-orient:vertical;'+
            'display:-webkit-box;-webkit-line-clamp:2;max-height:48px;line-height:1.4;'+
            'font-size:16px;color:#333;text-align:left;font-weight:bold;overflow:hidden">'+
            item_title +'</span>'+
            '<span class="ogpCard_description" style="overflow:hidden;text-overflow:ellipsis;'+
            'white-space:nowrap;line-height:1.6;margin-top:4px;color:#757575;text-align:left;'+
            'font-size:12px">'+ item_price +' '+ item_overview +'</span>'+
            '<span class="ogpCard_url" style="display:flex;align-items:center;margin-top:auto">'+
            '<span class="ogpCard_iconWrap" style="width: 20px;height:20px;flex-shrink:0">'+
            '<img src="https://www.google.com/s2/favicons?domain=https://www.amazon.co.jp" '+
            'style="vertical-align: 0; margin-right: 4px; min-width: 16px;"></span>'+
            '<span class="ogpCard_urlText" style="overflow: hidden; text-overflow: ellipsis; '+
            'white-space: nowrap; font-size: 13px; text-align: left; font-weight: bold; '+
            'color: rgb(34, 34, 34);">www.amazon.co.jp</span></span></span>'+

            '<span class="ogpCard_imageWrap" style="position:relative;width:120px;'+
            'height:120px;flex-shrink:0">'+
            '<img alt="card image" class="ogpCard_image" '+
            'data-ogp-card-image="" height="120" loading="lazy" src="'+ item_img_src +
            '" style="position:absolute;top:50%;left:50%;object-fit:contain;height:100%;'+
            'width:100%;transform:translate(-50%,-50%)" width="120"></span></a>'+
            '</article></div>';

        return card_tx;
    } // creat_card()



    function copy(){
        let copy_text;
        let tr_copy=document.querySelector('#tr_copy');
        if(tr_copy){
            tr_copy.onclick=function(){
                if(panel_disp==1){
                    if (navigator.clipboard){ // copyToClipboardを実行
                        if(action==0){
                            copy_text=url_input.textContent; }
                        else{
                            copy_text=creat_card(); }
                        navigator.clipboard.writeText(copy_text);

                        tr_copy.textContent='copied';
                        setTimeout(()=>{
                            tr_copy.textContent='Copy'; }, 1000); }}}}}



    function close(){
        let tr_panel=document.querySelector('#tr_panel');
        let tr_close=document.querySelector('#tr_close');
        if(tr_panel && tr_close){
            tr_close.onclick=function(){
                panel_disp=0;
                tr_panel.style.display='none'; }}}

} // main()




 

 

 

「Amazon Item_URL」最新版について 

旧いバージョンの JavaScriptツールは、Amazonサイトのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。

 

●「Amazon Item_URL」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。