node.jsのsync-requestとjsdomを使って、アマゾンから商品のasinを取得してみる。
まず、5月24日発売のkindleの本を例にとって取得する。browsenodeを変えると違う内容も同じように取得できるだろう。ページ数は4あり、それぞれを自動で切り替えて最終ページになるとbreakして止まるようにしている。sync-requestを利用しているので同期処理で書いています。
sync-requestとjsdomはそれぞれ、インストールする。
npm install sync-request
npm install jsdom
5月24日発売の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を配列として出力している。1ページあたり16冊まで表示する。
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で書き直した。指定日から指定日までのキンドルで発売された本をファイルとして出力する。
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("リクエスト開始");