Permalink
Browse files

add post

  • Loading branch information...
nguyenvanduocit committed Jan 3, 2019
1 parent 8e5b959 commit 8dab6bdcb9f45e0b36364a46f39fded6b32752d2
@@ -0,0 +1,146 @@
---
title: "Lấy thông tin app trên Play Store với Javascript"
date: 2018-03-08T14:06:27+07:00
tags: [scraping, JavaScript, NodeJs]
images:
- /articles/thu-thap-thong-tin-app-google-play/images/thumbnail.png
author:
name: vominh
github: vominh
draft: false
---

Google không cho phép lấy thông tin của các application trên Play Store vì vậy chúng ta sẽ phải dùng cách rất thông dụng là parse và lấy thông tin từ HTML của nó.

Bài viết này sẽ sử dụng Nodejs và một vài thư viện cần thiết mà mình sẽ đề cập trong từng đoạn code.

Bạn có thể thực thi code trong bài này ở local của bạn hoặc trên chính website này. Dưới các đoạn code có nút run, click vào nút run để thực thi code, bạn cũng có thể sửa code trực tiếp.

## Yêu cầu trước khi đọc bài

1. Biết JavaScript cơ bản
1. Đã cài NPM, Node.js và biết cái cài package bằng NPM
1. Biết element selector

## Request HTML

Link trang detail của một ứng dụng có cấu trúc như sau:

```
https://play.google.com/store/apps/details?id=<appID>
```

Mình có thể sử dụng thư viện request, nếu muốn promise thì dùng thêm request-promise-native.

```javascript
require('request')
const request = require('request-promise-native')
```

Sử dụng như sau:

```javascript
function getHTML(appID) {
return request(`https://play.google.com/store/apps/details?id=${appID}`)
}
```

Hàm này sẽ trả về promise, khi success thì chúng ta sẽ có HTML cần thiết.

## Parse fields

Sau khi có nội dung HTML của trang web, chúng ta cần parse nó ra thành dạng có cấu trúc thì mới query được, ở đây ta dùng thư viện cheerio, thư viện này cho phép chung ta query bằng element selector giống như trong jQuery vậy:

```javascript
function parseFields($) {
const detailsInfo = $('.details-info')
const title = detailsInfo.find('.document-title').text().trim()
return {
title
}
}
```

Các selector này có thể thay đổi bất cứ lúc nào, để biết các selector ở thời điểm hiện tại, bạn cần truy cập website trên Google Play và inspect element để biết selector của nó.

_Update ngày 11/06/2018: Google đã không dùng class có tên dễ hiểu nữa mà đổi qua auto-generated-class, muốn query giờ phải tính toán nhiều hơn, xem mã nguồn của [google-play-scraper](https://github.com/facundoolano/google-play-scraper) để biết thêm_

Gộp tất cả lại chúng ta có đoạn code như sau:

{{% runkit 1546499442715%}}
```
require('request')
const request = require('request-promise-native')
const cheerio = require('cheerio')
function getHTML(appID) {
return request(`https://play.google.com/store/apps/details?id=${appID}`)
}
function parseFields($) {
const title = $('h1[itemprop=name]').text().trim()
return {
title
}
}
function getAppInfo(appId) {
return getHTML(appID)
.then(cheerio.load)
.then(parseFields)
.catch(error => {
console.log(error)
})
}
const appID = 'com.orangenose.riskyrider'
const appInfo = await getAppInfo(appID)
console.log(appInfo)
```
{{% /runkit %}}

Bạn có thể chạy thử để thấy kế quả. Như vậy coi như là đã xong, không có gì quá phức tạp cả.

## Thư viện

Nhưng nếu bạn không muốn tự code thì cũng có thể sử dụng thư viện có sẵn của facundoolano: google-play-scraper. Những gì mình hướng dẫn bạn ở phía trên là mình học được khi đọc thư viện này.

Thư viện google-play-scraper chung cấp nhiều chức năng tiện dụng hơn:

1. app: Lấy tất cả thông tin của app.
1. list: Lấy danh sách app từ collection trên Google Play.
1. search: Tìm kiếm app.
1. developer: Lấy danh sách app của developer.
1. suggest: Lấy kết quả auto suggest từ chuỗi bạn truyền vào.
1. reviews: Lấy review của một app.
1. similar: lấy danh sách các app tương tự.
1. permissions: Lấy dánh sách permission của app.

Bạn đọc đầy đủ tài liệu tại repo của thư viện.

## Cài đặt

```
npm install google-play-scraper
```

hoặc

```
yarn add google-play-scraper
```

## Sử dụng

Khá đơn giản:

```
let gplay = require('google-play-scraper');
let appInfo = await gplay.app({appId: 'org.senviet.nentangdaoduc'})
console.log(appInfo)
```

## Lời kết

Ngoài ra thì tác giả này cũng làm thêm thư viện để lấy thông tin của app trên App: [App Store Scraper](https://github.com/facundoolano/app-store-scraper). Bạn cũng có thể viết ứng dụng để lấy tên nhạc trên Zing theo cách tương tự.

@@ -509,3 +509,14 @@ figcaption{
border: solid 1px #DDEEEE;
padding: 10px;
}

.tags-section{
.tag{
text-decoration: none;
color: #56bd77;
padding: 5px;
background: #f3f3f3;
border-radius: 4px;
font-size: 12px;
}
}
@@ -1,29 +1,29 @@
<section id="js_comment" class="comment single-section" data-slug="{{ .URL }}">
<h1 class="comment__title single-section__title">Comments</h1>
<h1 class="comment__title single-section__title">Bình luận</h1>
<div class="comment__form">
<div class="comment__form-input">
<textarea name="content" id="content" @focus="isFocusOnContent = true" v-model="content" placeholder="What are you thinking?"></textarea>
<textarea name="content" id="content" @focus="isFocusOnContent = true" v-model="content" placeholder="Bạn đang nghĩ gì?"></textarea>
</div>
<template v-if="isFocusOnContent">
<div class="comment__form-input">
<label for="anonymous">
<input type="checkbox" id="anonymous" v-model="isAnonymous">
<span>comment as an anonymous</span>
<span>Bình luận ẩn danh</span>
</label>
</div>
<template v-if="!isAnonymous">
<div class="comment__form-input">
<label for="name">Name</label>
<label for="name">Tên</label>
<input type="text" id="name" name="name" v-model="author">
</div>
<div class="comment__form-input">
<label for="email">Email <span>(optional)</span></label>
<label for="email">Email</label>
<input type="email" id="email" name="email" v-model="email">
</div>
</template>
</template>
<div class="comment__form-input">
<input type="submit" value="Post comment" @click.prevent="postComment">
<input type="submit" value="Gửi bình luận" @click.prevent="postComment">
</div>
</div>
<div class="comment__list">
@@ -1,7 +1,7 @@
<section class="single-section">
{{ $related := .Site.RegularPages.Related . | first 5 }}
{{ with $related }}
<h1 class="single-section__title">See Also</h1>
<h1 class="single-section__title">Đọc thêm</h1>
<ul>
{{ range . }}
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
@@ -1,6 +1,6 @@
{{ if .GitInfo }}
<section class="gitinfo single-section">
{{ $commit := getJSON "https://api.github.com/repos/12bitvn/12bit.vn/git/commits/" .GitInfo.Hash }}
<p>Last commit by {{ $commit.committer.name }} on {{ $commit.committer.date| dateFormat "January 02, 2006" }}: <a href="{{$commit.html_url}}" target="_blank">open on Github</a></p>
<p>Sửa lần cuối bởi {{ $commit.committer.name }} vào ngày {{ $commit.committer.date| dateFormat "January 02, 2006" }}: <a href="{{$commit.html_url}}" target="_blank">open on Github</a></p>
</section>
{{ end }}
@@ -2,14 +2,10 @@ name: Minitil
license: MIT
licenselink: 'https://github.com/12bit/minitil/blob/master/LICENSE'
description: Minimal TIL theme for Hugo
homepage: 'http://example.com/'
homepage: 'https://12bit.vn/'
tags: []
features: []
min_version: '0.41'
author:
name: 12bit
homepage: 'https://12bit.vn'
original:
name: ''
homepage: ''
repo: ''

0 comments on commit 8dab6bd

Please sign in to comment.