Amazonの検索結果からasinをスクレイピング

node.jsのsync-requestとjsdomを使って、アマゾンから商品のasinを取得してみる。

　まず、５月２４日発売のkindleの本を例にとって取得する。browsenodeを変えると違う内容も同じように取得できるだろう。ページ数は４あり、それぞれを自動で切り替えて最終ページになるとbreakして止まるようにしている。sync-requestを利用しているので同期処理で書いています。
sync-requestとjsdomはそれぞれ、インストールする。

```
npm install sync-request
npm install jsdom
```

５月２４日発売のkindleの本のURL
https://www.amazon.co.jp/s?i=digital-text&bbn=2275256051&rh=n%3A2250738051%2Cn%3A2275256051%2Cp_n_date%3A20200524&dc&qid=1588732789&ref=sr_ex_n_1


　日付やページの部分を書き換えて自動で取得している。
ページからjsdomでasinを配列として出力している。１ページあたり１６冊まで表示する。

```js

var request = require('sync-request');
 const jsdom = require("jsdom");
const { JSDOM } = jsdom;
fs = require('fs');

day=20200524
flag=1
asinarray=[]

loop1:for (let i =1; i <=100;  i ++) {
var url = 'https://www.amazon.co.jp/s?i=digital-text&rh=n%3A2250738051%2Cn%3A2250739051%2Cn%3A2275256051%2Cp_n_date%3A'+day+'&s=date-desc-rank&page='+i+'&qid=1588652675&ref=sr_pg_2'
//console.log(url)
if(flag==0){break;}
html = httpGet(url);
asin=asinGet(html)
asinarray=asinarray.concat(asin)
}

console.log(asinarray)


function httpGet(url){
  var res = request(    'GET',    url    );
response=  res.getBody('utf-8')
//console.log(response);
    return response;
}
function asinGet(html){
    const dom = new JSDOM(html);
table=dom.window.document.querySelectorAll("h2.a-size-mini > a")
asin=[]//配列宣言
for (let i = 0; i < table.length; i++) {
asin[i]=table[i].href
asin[i]=asin[i].replace( /^.+dp\/(\w+)\/.+$/g , '$1' )
}

if(dom.window.document.querySelectorAll("ul.a-pagination > li").length !== 0){

li=dom.window.document.querySelectorAll("ul.a-pagination > li")
flag=li[li.length-1].getElementsByTagName('a').length
}
else{flag=0}
console.log(asin)
console.log(flag)
return asin
}
```
async/await.Promiseで書き直し

sync-requestでやるとページ数が多いときにエラーが出たので、async/await、Promiseで書き直した。指定日から指定日までのキンドルで発売された本をファイルとして出力する。

```js
const request = require("request");
 const jsdom = require("jsdom");
const { JSDOM } = jsdom;
fs = require('fs');

function asinGet(html){
    const dom = new JSDOM(html);
table=dom.window.document.querySelectorAll("h2.a-size-mini > a")
asin=[]//配列宣言
for (let i = 0; i < table.length; i++) {
asin[i]=table[i].href
asin[i]=asin[i].replace( /^.+dp\/(\w+)\/.+$/g , '$1' )
}
/*
ul class="a-pagination" li class="a-disabled a-last"
*/
if(dom.window.document.querySelectorAll("ul.a-pagination > li").length !== 0){

li=dom.window.document.querySelectorAll("ul.a-pagination > li")
flag=li[li.length-1].getElementsByTagName('a').length
}
else{flag=0}
console.log(asin)
console.log(flag)
return asin
}

function sleep(second) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve()
        }, second * 1000)
    })
}

function requestPromise(param){
    return new Promise((resolve, reject)=>{
        request(param, function (error, response, body) {
            if(error){
                reject("ページを取得できませんでした");
            }else{
//                console.log(body);
                asin=asinGet(body)
                asinarray=asinarray.concat(asin)
                resolve("取得できました");
            }
        })
    })
}

(async function(){

day=20200602
today=20200602
for (day; day <= today; day++) {
flag=1
asinarray=[]
filename=day+'k.json'
for (let i =1; i <=300;  i ++) {
var url = 'https://www.amazon.co.jp/s?i=digital-text&rh=n%3A2250738051%2Cn%3A2250739051%2Cn%3A2275256051%2Cp_n_date%3A'+day+'&s=date-desc-rank&page='+i+'&qid=1588652675&ref=sr_pg_2'
if(flag==0){break;}
 await sleep(3) 
await requestPromise(url);
  }
  
  console.log(asinarray)
  console.log('ファイルを書き込みます')
fs.writeFileSync(__dirname + '/json/kindle_asin/'+filename, JSON.stringify(asinarray, null, 1),'utf-8')
}
})();
console.log("リクエスト開始");
```

参考
https://qiita.com/KuwaK/items/6455e34c245992a73aa1