75075


EmEditorで特定サイトの文字を丸ごと取得することは可能でしょうか？  
たとえば、このサイトだと、クチコミなども含めて、数ページになるのを一機に取得できるかです。

<https://www.amazon.co.jp/dp/B08R9GYRQG/>

機能として出来るのか、そうしたことはできないのかだけでも教えていただけますと幸いです。


CC BY-SA 4.0
2021-03-25T05:16:48.713
74883
2021-04-10T10:30:29.617
2021-04-10T10:30:29.617
3060
43999
question
emeditor
EmEditorによるwebページの文字列取得


標準状態の EmEditor から直接、任意の web page へのアクセス手段はありませんが、  
プラグインやマクロで機能を拡張できるので、出来るようにすることは可能です。  
実用性は低いのですが実証用のマクロを作ってみました。

url2txt.jsee

[code]

    #title="url -> text"
    
    /*
        目的の url, ASIN, ISBN どれかを、文字列選択かクリップボードへコピーして起動。
        ・url ならば、テキストだけ抜き出してアウトプットバーへ出力。
        ・ASIN,ISBN-10,ISBN-13(978) ならば、amazon からテキスト化してレビューページも保存、
          保存先は現在開いているドキュメントと同じディレクトリ、
          アウトプットバーへ、タグジャンプ用のリンクを出力。
        ・どちらも汎用のテキスト変換処理なので精度は低い。
    
        テストページ
        https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html        UTF-8 国民の祝日について - 内閣府
        https://eco.mtk.nao.ac.jp/koyomi/yoko/                      Sift_JIS  暦要項 - 国立天文台暦計算室
        http://weather.goo.ne.jp/earthquake/index.rdf               RSS 地震情報 - goo天気
        https://news.yahoo.co.jp/rss/topics/top-picks.xml           RSS Yahoo!ニュース・トピックス - 主要
        400339481X                                                  ISBN-10 ウィーナー サイバネティックス――動物と機械における制御と通信 (岩波文庫)
        978-4003394816                                              ISBN-13 ウィーナー サイバネティックス――動物と機械における制御と通信 (岩波文庫)
    */
    
     var AmazonReviewLimit = 30;    // 取得ページ数上限
     var Amazon_foreign = true;     // 外国のレビューを有効にする
    
     var f_Review = true;           // レビュー保存
     var DL_Root = document.Path;   // 保存場所
    
    
    function netGet( url, agent ){
        var res = {};
        res.body = "";
        res.code = "";
        try {
            var xhr = new ActiveXObject("Msxml2.ServerXMLHTTP");    // Msxml2.ServerXMLHTTP.6.0
            xhr.open( "GET", url, true );
            if( agent ){
                xhr.setRequestHeader( "User-Agent", agent );    // "" は xhr が受け付けない、" " だと、空の文字列("") になる
            }
            xhr.send();
            for( var rty = 1000; xhr.readyState != 4 && rty > 0; --rty ){ xhr.waitForResponse(100); }
            if( xhr.readyState == 4 ){
                res.code = xhr.status;
                res.status = xhr.statusText;
                res.bytes = xhr.responseBody;
                if( xhr.status == 200 ){ res.body = xhr.responseText; }
            } else {
                xhr.abort();
                alert( "Error abort" );
            }
        } catch (e) {
            alert( "Error (" + e.number + ") " + e.name + " : " + e.message + " )" );
        }
        return res;
    }
    
    // txt化 簡易処理、<pre> 等未対応
    function htm2txt( buff ){
        buff = buff.replace( /\n/g, " " );
    
        var m = buff.match( /<title>(.*?)<\/title>/i );
        var title = (m != null && m.length > 1)? m[1] : "";
    
        buff = buff.replace( /<!--.*?-->/mg, " " );
        buff = buff.replace( /<head[\s>].*?<\/head>/i, " " );
    
        buff = buff.replace( /<script[\s>].*?<\/script>/gi, " " );
        buff = buff.replace( /<noscript[\s>].*?<\/noscript>/gi, " " );
        buff = buff.replace( /<style[\s>].*?<\/style>/gi, " " );
    
        buff = buff.replace( /&#x([\dA-F]+);/ig, function( c0, c1 ){ return String.fromCharCode( parseInt( c1, 16 ) ); } );
    
        buff = buff.replace( /&nbsp;?/gi, " " );
        buff = buff.replace( /\s+/g, " " );
    
        buff = buff.replace( /<\/(div|p|h\d|tr|ol|ul|li|pre|title|item|description|pubDate|entry)\b>/gi, "\n" );    // 段落 等
        buff = buff.replace( /<br(\s*|\b[^>]*)>/gi, "\n" );
    
        buff = buff.replace( /<.*?>/g, " " );
        buff = buff.replace( /\s+$/gm, "\n" );
    
        buff = buff.replace( /&lt;?/gi, '<' ).replace( /&gt;?/gi, '>' ).replace( /&quot;?/gi, "\"" ).replace( /&apos;?/gi, "'" );
    
        buff = buff.replace( /&amp;?/gi, '&' );
        return [buff, title];
    }
    
    // amazon review 抜き出し 専用
    function review2txt( buff, page ){
        buff = buff.replace( /\n/g, " " );
    
        var m = buff.match( /<title>(.*?)<\/title>/i );
        var title = (m != null && m.length > 1)? m[1] : "";
    
        buff = buff.replace( /<!--.*?-->/mg, " " );
        buff = buff.replace( /<head[\s>].*?<\/head>/i, " " );
    
        buff = buff.replace( /<script[\s>].*?<\/script>/mgi, " " );
        buff = buff.replace( /<noscript[\s>].*?<\/noscript>/mgi, " " );
        buff = buff.replace( /<style[\s>].*?<\/style>/mgi, " " );
    
        var revList = "";
        var rev_count = 0;
        for( var no = 1; true; ++ no ){
            var m = buff.match( /^.*? id="[\w\d]+-review-card" .*?>(.*?>)違反を報告<\/a>(.*)$/i );
            if( m == null || m.length < 2 ) break;
            buff = m[2];
            if( ! Amazon_foreign && m[1].match( / id="customer_review_foreign-/ ) ) continue;
            ++ rev_count;
    
            imh = {};
            m[1] = m[1].replace( /<img alt="カスタマー画像" src="\s*(https:\/\/images-na\.ssl-images-amazon\.com\/images\/I.*?)\s*".*?>/ig,
                function( cap0, cap1 ){
                    if( imh[cap1] == true ){ return " "; }
                    imh[cap1] =  true;
                    var href = cap1.replace( /\._SY88\./, '.' );
                    return "<br> " + href + " ";
            } );
    
            var txt = htm2txt( m[1] );
            revList += txt[0];
            revList += "\n<------------ " + ('  '+page).slice(-3) + " - " + (' '+no).slice(-2) + " ------------>\n";
        }
    
        return [revList, title, rev_count];
    }
    
    // amazon review page 巡回
    function amazonReviews( asin, rootDir, f_Review ){
        amazon_agent = " "; // Amazon は標準の User-Agent だと弾かれる。
        var htm = netGet( "https://www.amazon.co.jp/dp/" + asin, amazon_agent );
        if( htm.body == "" ){ return }
    
        var txt = htm2txt( htm.body );
        var fpath = rootDir + "\\" + "amazon_" + asin + ".txt";
        var topFpath = "" + fpath;
    
        editor.NewFile();
        document.Encoding = 65001;
        document.UnicodeSignature = false;
        document.write( txt[1] + "\n\n" + txt[0] ); // title + body
        document.selection.StartOfDocument();
        document.Save( fpath );
        OutputBar.writeln( fpath + "(1):" );
    
        if( f_Review ){
            var next_url = "";
            for( var no = 1; no <= AmazonReviewLimit; ++ no ){
                Sleep( 1 );
                htm = (next_url == "")?
                    netGet( "https://www.amazon.co.jp/product-reviews/" + asin + "/?pageNumber=" + no + "&reviewerType=all_reviews", amazon_agent ) :
                    netGet( next_url, amazon_agent );
                if( htm.body == "" ){ break }
                next_url = "";
                var f_next = (htm.body.search( / class="a-last".*?<a\s+href="(.*?)".*?>次へ</im ) >= 0);
                if( f_next ){
                    next_url = RegExp.$1.replace( /^.*?\/(product-reviews\/.*)$/, "https://www.amazon.co.jp/$1" );
                    next_url = next_url.replace( /&amp;/g, "&" );
                }
                txt = review2txt( htm.body, no );
                if( txt[2] != 0 ){
                    fpath = rootDir + "\\" + "amazon_"  + asin + "_" + ('00'+no).slice(-3) + ".txt";
                    editor.NewFile();
                    document.Encoding = 65001;
                    document.UnicodeSignature = false;
                    document.write( txt[1] + "\n\n" + txt[0] );
                    document.selection.StartOfDocument();
                    document.Save( fpath );
                    document.close();
                    OutputBar.writeln( fpath + "(1):" );
                } else {
                    OutputBar.writeln( "Page: " + no + " Review Count == 0 : Amazon_foreign = " + Amazon_foreign );
                }
                if( ! f_next )  break;
            }
        }
        OutputBar.writeln( "Done." );
    
        editor.OpenFile( topFpath );
    }
    
    function bytes2utf8( bytes, enc ){
        var fh1 = new ActiveXObject("ADODB.Stream");
        fh1.Type = 1;
        fh1.Open();
        fh1.Write( bytes );
        fh1.Position = 0;
        fh1.Type = 2;
        fh1.Charset = enc;
        rval = fh1.ReadText();
        fh1.Close();
        return rval;
    }
    
    function url2txt( url ){
        var htm = netGet( url );
        if( htm.body == "" ){ return }
        if( /<meta[^>]*\bcharset[\s="']+(Shift_JIS|EUC-JP)/im.test( htm.body ) ){
            switch( RegExp.$1.toLowerCase() ){
            case "shift_jis":   htm.body = bytes2utf8( htm.bytes, "SJIS" );     break;
            case "euc-jp":      htm.body = bytes2utf8( htm.bytes, "EUC-JP" );   break;
            }
        }
        var txt = htm2txt( htm.body );
        OutputBar.writeln( txt[1] + "\n\n" );   // title
        OutputBar.writeln( txt[0] );            // text
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // MAIN
    
        OutputBar.Clear();
        OutputBar.Visible = true;
    
        var stropt = document.selection.Text.replace( /^\s+|\s+$/g, '' );
        if( stropt.length == 0 ){
            stropt = clipboardData.getData( "Text" ).replace( /^\s+|\s+$/g, '' );
        }
    
        if( stropt.search( /^https?:.*/ ) >= 0 ){
            url2txt( stropt );
            Quit();
        }
    
        if( stropt.search( /^B0[A-Z\d]{8}$/ ) >= 0 ){   // ASIN
            amazonReviews( stropt, DL_Root, f_Review );
            Quit();
        }
    
        if( stropt.search( /^[\s\dX-]+$/ ) >= 0 ){      // ISBN-10
            var isbn = stropt.replace( /[\s-]/g, '' );
            if( isbn.length == 10 ){
                var chk = 0;
                for( var i = 0; i < 9; ++ i ){
                    chk += parseInt( stropt.charAt(i) ) * (10-i);
                }
                chk = (11 - (chk % 11)) % 11;
                chk = (chk == 10)? 'X' : String( chk );
                if( chk == stropt.charAt(9) ){
                    amazonReviews( stropt, DL_Root, f_Review );
                    Quit();
                }
            }
        }
        if( stropt.search( /^[\d\s-]+$/ ) >= 0  ){      // ISBN-13 978
            var isbn = stropt.replace( /[\s-]/g, '' );
            if( isbn.length == 13 && isbn.substr(0,3) == '978' ){
                var chk = 0;
                for( var i = 0; i < 13; ++ i ){
                    chk += parseInt( isbn.charAt(i) ) * (2*(i&1) + 1);
                }
                chk = (10 - (chk % 10)) % 10;
                if( chk == 0 ){
                    for( var i = 3; i < 12; ++ i ){
                        chk += parseInt( isbn.charAt(i) ) * (13-i);
                    }
                    chk = (11 - (chk % 11)) % 11;
                    isbn = isbn.substr(3,9) + ((chk == 10)? 'X' : String( chk ));
                    amazonReviews( isbn, DL_Root, f_Review );
                    Quit();
                }
            }
        }
        OutputBar.writeln( "*** '" + stropt + "' ***" );    // 対象外
    
[/code]

* * *

  * 仕様  
Amazon は [www.amazon.co.jp](http://www.amazon.co.jp)
の日本語ページだけに対応。「カスタマー画像」など日本語のメッセージから処理しているため。

  * 改変  
2021/04/09 amazonReviews() バグ改善、Review.bat は精度が低いので削除。  
Amazon_foreign 追加、false で国内からのレビューに限定。


CC BY-SA 4.0
2021-04-04T03:35:48.430
75075
2021-04-09T11:24:13.203
2021-04-09T11:24:13.203
40304
40304
74883
answer