我在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;
}
}
有没有什么办法可以通过检查第一个空输出来找出最大页数?或为此目的的任何其他建议?
所以有几个问题,它看起来像你的使用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);
})
我尝试这样实现。请尝试让我知道它是否有效:)
在reviews的文件中,请注意:
请注意,此方法以特定语言(默认为英语)返回评论,因此您需要尝试不同的语言才能获得更多评论。此外,Google Play页面中显示的计数器是指应用程序拥有的1-5星评级总数,而不是书面评论数。因此,如果应用程序的评级为100k,则不要期望使用此方法获得100k评论。
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))
问题是我应该预先定义每个应用程序拥有的最大页面数量(我应该确定循环的i的最大值)。
我想我们可以从app
回复得到这些数据。
{
appId: 'es.socialpoint.chefparadise',
...
ratings: 27904,
reviews: 11372, // data to determine pagenumber
...
}
此外,review
还提供了用于页码计算的球场号码。
page(可选,默认为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 评测 ....