[2021/05/22更新]FlutterでWebスクレイピング(QiitaのマイページからLGTMの数を取得)
※2021/4/13追記
現在、QiitaのURLが変更されており、そのままだと動かなくなってしまっています。時間見つけて更新したいです。
※2021/5/22追記
URLの変更に対応しました。
なぜFlutterでスクレイピングしようと思ったのか
きっかけはQiitaのアプリを作成中に、QiitaのユーザAPIからは、LGTM数が取得出来ないことに気づいたことでした。
しかし以前LGTM数のランキングのようなものを見たことある気がしたので、調べるとWebスクレイピングをしてランキングを作成されているようだったので、アプリから自分のLGTM数を取得しようと思うとスクレイピングするしかないと考えました。
※Webスクレイピングは、マナーや規約に気をつけて実施する必要があります。
実現までに考えたこと
Webスクレイピングと言えば、Pythonなどを中心にライブラリが多く、あまりスクレイピングの経験も少なかったりしたので、今回はまずPythonで実際に情報を取得するようにしました。
いきなりFlutterから実践しても良いと思いますが、私のように自信がなかったり、スクレイピング自体が久しぶりの人はスクリプト言語で試してみると良いと思います。その方が情報も豊富なので。
STEP1: Pythonのスクリプトで自分のマイページからLGTM数を取得
STEP2: Flutterで実現する方法を考える
STEP3: サンプルアプリ実装
という順番で実践しました。
STEP1: Pythonのスクリプトで自分のマイページからLGTM数を取得
今回は情報が豊富なPythonのBeaufulSoupを使いました。以下の記事などを参考にしました。
Python Webスクレイピング テクニック集「取得できない値は無い」JavaScript対応@追記あり6/12
動作環境: Python 3.9.1
# coding: UTF-8
import requests
from bs4 import BeautifulSoup
# 自分のアカウントのQiitaのマイページのURL
url = "https://qiita.com/toda-axiaworks"
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0"}
response = requests.get(url=url, headers=headers)
html = response.content
soup = BeautifulSoup(html, "html.parser")
# セレクタは、上記の記事を参考に記述しました
selector = "span.css-mf9wc5"
print(soup.select_one(selector).text)
python qiita_lgtm.py
を実行すると、109
と正しい結果が返ってきました。(2020/02/14時点)
ここでセレクタのパラメータなどが正しいことを、しっかり確認しました。
STEP2: Flutterで実現する方法を考える
なるべくライブラリの力を借りたかったので、ライブラリを探しました。
今回は、universal_htmlというライブラリを使用しました。主な理由はSTEP1で作成したPythonのコードと、ほとんど同じコードで情報が取得出来ることが分かったことが、大きなポイントでした。
(当初は別のライブラリで実装を試みたのですが、サンプルも少なく、私があまり使いこなせなかったこともあり、universal_htmlを採用しました。)
STEP3: サンプルアプリ実装
STEP2で挙げたuniversal_htmlを使うことで、ほぼSTEP1のPythonコードを再現するだけでFlutterアプリ上で取得したかった情報が表示出来ました。
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
universal_html: ^1.2.4 // 今回インストールするライブラリ
(以下略)
pubspec.yamlに追加するライブラリ情報を記載して、
pub get
コマンドを実行します。メインのコードは以下のようになりました。
import 'package:flutter/material.dart';
import 'package:universal_html/driver.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Qiita LGTM',
theme: ThemeData(
primarySwatch: Colors.lightGreen,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyLgtmNumberPage(),
);
}
}
class MyLgtmNumberPage extends StatefulWidget {
@override
_MyLgtmNumberPageState createState() => _MyLgtmNumberPageState();
}
class _MyLgtmNumberPageState extends State<MyLgtmNumberPage> {
// 最終的にはBaseURLにAPIから取得したユーザーIDを渡せば良さそう
static const url = 'https://qiita.com/toda-axiaworks';
String _lgtmNumber = '';
@override
void initState() {
super.initState();
_getQiitaLgtmNumber();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Qiita LGTM Sample',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
body: Center(
child: _lgtmNumber.isNotEmpty
? _RoundLgtm(
label: _lgtmNumber,
)
: CircularProgressIndicator(),
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.refresh,
color: Colors.white,
),
onPressed: _getQiitaLgtmNumber,
),
);
}
_getQiitaLgtmNumber() async {
final driver = HtmlDriver();
await driver.setDocumentFromUri(Uri.parse(url));
setState(() {
_lgtmNumber = driver.document
.querySelector("span.css-mf9wc5")
.text;
});
}
}
// LGTM数を表示する円型のWidget
class _RoundLgtm extends StatelessWidget {
const _RoundLgtm({
this.label,
});
final String label;
@override
Widget build(BuildContext context) {
return Container(
width: 200,
height: 200,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.lightGreen,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
label,
style: TextStyle(
color: Colors.white,
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
Text(
'LGTM',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
],
),
);
}
}
まとめ
ひとまずLGTMの数字がアプリ上で表示できていることを確認出来ました。今回は特にSTEP1で最初にPythonで動作をしっかり確認して、それをFlutter側で同じように実装を行えたことで、とてもやりやすくなりました。
サンプルなので固定のURLになっていますが、https://qiita.com/toda-axiaworks というURLなので、https://qiita.com/ のベースURLにAPIから取得したユーザIDを渡せば、他のユーザーの情報も表示出来そうです。
念のため試したところ、他のユーザーのLGTMを表示することも出来ました。
Author And Source
この問題について([2021/05/22更新]FlutterでWebスクレイピング(QiitaのマイページからLGTMの数を取得)), 我々は、より多くの情報をここで見つけました https://qiita.com/toda-axiaworks/items/dd05264d5a7953316494著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .