我正在使用node.js中的google-play-scraper模块来抓取Google Play评论。单个页面的查看功能如下:
var gplay = require('google-play-scraper');
gplay.reviews({
appId: 'es.socialpoint.chefparadise',
page: 0,
}).then(console.log, console.log);
现在,我想一次在所有页面上抓取所有评论,并将其保存在记录器中。为此,我正在使用winston logger和如下的for循环:
var gplay = require('google-play-scraper');
const winston= require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'rev1.log' })
]
});
package_id='com.jetstartgames.chess'
for (i=0; i<112; i++){
gplay.reviews({
appId: package_id,
page: i,
}).then(logger.info, logger.info);
}
问题是我应该为每个应用程序预定义其评论所拥有的最大页面数(我应该为循环确定i的最大值)。为了做到这一点,我教过检查空值,但是我找不到可行的方法。实际不存在的页面的日志文件具有以下结构:
{“消息”:[],“级别”:“信息”}
我尝试了以下无效的代码:
max=0
for (i=0; i<10000; i++){
data=gplay.reviews({
appId: 'com.jetstartgames.chess',
page: i,
});
if (data.message==null || data.message==undefined){
break;
} else {
max+=1;
}
}
是否可以通过检查第一个空输出来找出最大页数?或为此目的有其他建议吗?
答案 0 :(得分:0)
所以有两个问题,您使用的api似乎使用了Promises,因此返回值直到进一步循环时才可用。
如果您使用的是node.js> 7.6,则可以这样使用async / await;
import gplay from 'google-play-scraper';
async function getReviews(appId, page = 1) {
return await gplay.reviews({
appId,
page,
});
}
async function process(appId) {
let page = 1;
let messages = [];
let result;
do {
result = await getReviews(appId, page);
messages = messages.concat(result);
++page;
} while (result.length > 0);
return messages;
}
process('com.jetstartgames.chess')
.then((messages) => {
console.log(messages);
})
答案 1 :(得分:0)
我尝试这样实现。请尝试让我知道是否可行:)
在reviews的文档中,请注意:
请注意,此方法以特定语言(英文)返回评论 默认情况下),因此您需要尝试其他语言才能获得更多 评论。另外,在Google Play页面中显示的计数器是指 应用程式拥有的1-5星评分总数,而不是 书面评论计数。因此,如果该应用程序的评级为100k,请不要期望 使用此方法可获得10万条评论。
var gplay = require('google-play-scraper');
var appId = 'com.jetstartgames.chess';
var taskList = [];
for(var i = 1 ; i < 10000; i++){
taskList.push(new Promise((res, rej)=>{
gplay.reviews({
appId: appId,
page: i,
sort: gplay.sort.RATING
}).then(result =>{
res(result.length);
})
.catch(err => rej(err))
}));
}
Promise.all(taskList)
.then(results => {
results = results.filter(x => x > 0);
var maxPage = results.length;
console.log('maxPage', maxPage);
})
.catch(err => console.log(err))
答案 2 :(得分:0)
问题是我应该为每个应用程序预定义其评论的最大页数(我应该为循环确定i的最大值)。
我认为我们可以从app
响应中获取此数据。
{
appId: 'es.socialpoint.chefparadise',
...
ratings: 27904,
reviews: 11372, // data to determine pagenumber
...
}
此外,review
为页码计算提供了一个停球场编号。
页面(可选,默认为0):包含评论的页面数。每个页面最多有40条评论。
进行这些更改,
'use strict';
const gplay = require('google-play-scraper');
const packageId = 'es.socialpoint.chefparadise';
function getAppDetails(packageId) {
return gplay.app({ appId: packageId })
.catch(console.log);
}
getAppDetails(packageId).then(appDetails => {
let { reviews, ratings } = appDetails;
const totalPages = Math.round(reviews / 40);
console.log(`Total reviews => ${reviews} \nTotal ratings => ${ratings}\nTotal pages => ${totalPages} `);
let rawReview = [];
let pageNumber = 0;
while (pageNumber < totalPages) {
console.log(`pageNumber =${pageNumber},totalPages=${totalPages}`);
rawReview.push(gplay.reviews({
appId: packageId,
page: pageNumber,
}).catch(err => {
console.log(packageId, pageNumber);
console.log(err);
}));
pageNumber++;
}
return Promise.all(rawReview);
}).then(reviewsResults => {
console.log('***Reviews***');
for (let review of reviewsResults) {
console.log(review);
}
}).catch(err => {
console.log('Err ', err);
});
对于带有较少评论的packageId来说效果很好。但是对于es.socialpoint.chefparadise
,由于数据量巨大,我经常遇到Issue #298。
输出
总评论=> 215922
总评分=> 688107
总页数=> 5398
评论
....