teratail header banner
teratail header banner
質問するログイン新規登録
teratail

teratail(テラテイル)は、プログラミングに特化した日本語Q&Aサイトです。

Q&A

解決済

5回答

1858閲覧

タグごとの未回答、未解決の質問数を知るにはどうしたらよいですか?

katoy

総合スコア22328

teratail

teratail(テラテイル)は、プログラミングに特化した日本語Q&Aサイトです。

3グッド

1クリップ

投稿2016/03/19 01:12

3

1

タグごとの未回答、未解決の質問数を知るにはどうしたらよいですか?

例えば
https://teratail.com/tags/JUnit
をみた場合、
総質問数 91件
が表示されるだけで、未回答、未解決, 解決の数はわかりません。

なぜ、こんな数が知りたいかというと、
未回答、未解決の割合が多いタグを見つけて、それらになるべく回答をしてみたい
と思っているからです。

teratail API を使えば、集計数を得ることはできるのかもしれませんけど ...

蛇足:
時系列変化を知りたい各種の数値があるのですが、現時点の teratail 画面には時系列系の画面は存在していませんね.

issei., ps13zier, maisumakun👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

APIから取得するツールを作りました。Ruby 2.3.0でしか動かないかも。

Ruby

1# frozen_string_literal: true 2# teratail.rb 3# The MIT License (MIT) 4# Copyright (c) 2016 raccy 5# see https://opensource.org/licenses/MIT 6 7require 'net/http' 8require 'uri' 9require 'json' 10 11class Teratail 12 TERATAIL_API_V1 = 'https://teratail.com/api/v1/' 13 MAX_LIMIT = 100 14 15 def initialize(access_token = nil, uri = TERATAIL_API_V1) 16 @access_token = access_token 17 @uri = URI(uri) 18 end 19 20 def get(*paths, **params) 21 request_uri = @uri 22 .merge(paths.map { |path| URI.encode_www_form_component(path) }.join('/')) 23 .merge("?#{URI.encode_www_form(params)}") 24 http = Net::HTTP.new(request_uri.host, request_uri.port) 25 http.use_ssl = true if request_uri.scheme == 'https' 26 http.start do 27 req = Net::HTTP::Get.new(request_uri.path + '?' + request_uri.query) 28 req['Authorization'] = @access_token if @access_token 29 http.request(req) do |response| 30 return response.code, JSON.parse(response.body) 31 end 32 end 33 end 34 private :get 35 36 def questions(tag = nil) 37 if block_given? 38 page = 1 39 total_page = 1 40 while page <= total_page 41 if tag 42 code, data = get('tags', tag, 'questions', 43 limit: Teratail::MAX_LIMIT, page: page) 44 else 45 code, data = get('questions', 46 limit: Teratail::MAX_LIMIT, page: page) 47 end 48 raise "#{code}: #{data.dig('meta', 'message')}" if code.to_i != 200 49 data['questions'].each do |question| 50 yield question 51 end 52 page += 1 53 total_page = data.dig('meta', 'total_page').to_i 54 end 55 else 56 to_enum(:questions, tag) 57 end 58 end 59end 60 61if __FILE__ == $PROGRAM_NAME 62 if ARGV.size > 0 63 tag_name = ARGV[0] 64 access_token = nil 65 # access_token = "Bearer 0123456789abcdef0123456789abcdef0123456789" 66 teratail = Teratail.new(access_token) 67 result = teratail.questions(tag_name) 68 .inject(no_reply: 0, no_accepted: 0) do |accs, q| 69 accs[:no_reply] += 1 if q['count_reply'] == 0 70 accs[:no_accepted] += 1 unless q['is_accepted'] 71 accs 72 end 73 puts "タグ: #{tag_name}" 74 puts "未回答: #{result[:no_reply]}" 75 puts "未解決: #{result[:no_accepted]}" 76 else 77 puts "引数にタグを指定して下さい。" 78 end 79end

上をteratail.rbとして保存して、実行した結果がこちら。

$ ruby teratail.rb React.js タグ: React.js 未回答: 1 未解決: 6 $ ruby teratail.rb Ruby タグ: Ruby 未回答: 124 未解決: 527

あまりテストしてないです。アクセストークン管理からアクセストークンを取得して、access_tokenを設定すると制限が緩くなります。トークン名はBearerとして下さい。やる気が出れば、そのうちちゃんと作ってgemにしたいと思います。

投稿2016/03/19 04:28

raccy

総合スコア21784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katoy

2016/03/19 09:47

投稿していただいたコードはとても参考になりました。
guest

0

企業秘密(?)ですが(^-^;
当社調べによると、JUnitの場合は91件中、未回答が2件、未解決が14件でした。

APIで質問一覧(questions)を取得すると、タグ名、回答数、BA有無の情報が含まれていますので、それで集計すればできます。

questionsは1回に付き100件取得できますので、トークンを最大数取得して回せば、今の質問数(現時点で30,000件程度)なら1時間もあれば全件取得できると思います。

投稿2016/03/19 03:30

argius

総合スコア9396

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2016/03/19 04:53

タグの質問一覧で取ったほうが効率が良いですね。 質問一覧は、他のケースでも応用できるということで。
katoy

2016/03/19 09:46

> ... 質問一覧は、他のケースでも応用できる ... はい、そうですね。 質問一覧を全部取得してから、いろいろな処理をする方法をとってみようと思います。
guest

0

面白い試みです。APiのタグ絡みを読みましたが使いやすくていいですね。
https://teratail.com/api/v1/tags/PHP/questions?limit=100&page=1

{"meta":{"message":"success","total_page":56,"page":2,"limit":100,"hit_num":5518},"tag":

1行目でlimitとpage情報がとられるので、PHPの場合、56回アクセスすれば割合が取れますね(吐血

3,000/hアクセスが可能なので、
(1ユーザーで10トークンを発行出来て、1トークン300/hアクセス)
APIを上手く使うサーバーを立ててCronで動かせば何とかならなくもない感じです。

投稿2016/03/19 03:02

miyabi-sun

総合スコア21465

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katoy

2016/03/19 09:50

> ... サーバーを立ててCronで動かせば .. そうですね。 でも各自がCron アクセスするより、teratail の API で全件を取得できるようにするとか、もっと API の機能を充実させて欲しいですね。
guest

0

これはchromeの場合だとデベロッパーツールを開きます。
networkのタブを開いておいて、未回答または未解決のタブを押したらAjaxが走ります。
p1~ではじまるURLがあるので、そのレスポンスに件数入ってます。previewタブを見たらよいかもしれません。

{"question_total":14,"html":"htmlが入ってます"}

ただ、タグ全体でどれが未回答だとかはタグ一覧を元にしてAPIを叩くしかなさそう・・・

投稿2016/03/19 01:16

編集2016/03/19 01:26
fagai

総合スコア2158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katoy

2016/03/19 09:52

> ... タグ一覧を元にしてAPIを叩く.. はい、そう思います。 もっと別の集計値を計算する可能性も考慮して、質問一覧を取得することから始めてみようと思います。
guest

0

目的の数値そのものではありませんが、質問一覧を取得してファイルび保存するものを作ってみました。
api で返ってくる json をそのまま保存しています。
このファイル群を別のプログラムで処理して、いろいろな統計数値を計算しようと思います。
2.rb

ruby

1require 'rubygems' if RUBY_VERSION < '1.9' 2require 'rest_client' 3require 'fileutils' 4 5DATA_DIR = 'teratails'.freeze 6URL = 'https://teratail.com/api/v1/questions'.freeze 7MAX_COUNT = 300 8 9start_page = 0 # 300, 600, ... 10 11headers = { 12 # https://teratail.com/users/setting/tokens で取得したトークンを "Bearer " の後に設定する 13 Authorization: 'Bearer xxxx' 14} 15 16(1..MAX_COUNT).each do |count| 17 page = start_page + count 18 response = RestClient.get("#{URL}?limit=100&page=#{page}", headers) 19 res = JSON.parse(response) 20 p "#-------- getting page:#{page}/#{res['meta']['total_page']}" 21 res['questions'].each do |q| 22 id = Integer(q['id']) 23 p id 24 dir = "#{DATA_DIR}/#{format('%06d', id / 100)}" 25 FileUtils.mkdir_p(dir) unless FileTest.exist?(dir) 26 file_name = "#{dir}/#{format('%06d', id)}.json" 27 File.write(file_name, q) 28 end 29end

実行をすると、質問の id 毎に json ファイルを teratails/ 以下に 保存します。

$ ls 2.rb $ time ruby 2.rb "#-------- getting page:1/299" 30188 30187 .... 省略 "#-------- getting page:299/299" .... 省略 real 8m40.541s user 1m57.950s sys 0m12.413s $ ls 2.rb teratails/

1つのトークンでは 100 * 300 = 3万件までしか質問の情報が得られません。
でもトークンは 10 個まで作れるようなので30万件までは一度で取得するようにできそうです。

追記:
tokenをコード中に書くより、$ export TERATAIL_TOKEN=xxxx などとしておいて、
ENV['TERATAIL_TOKEN'] で header に取得するほうが良さそう。

追記: 2016-03-26
https://github.com/katoy/teratails
に質問一覧の取得、タグ毎の集計をするためのプログラム群をおきました。(ruby + activerecord + sqlite3)

投稿2016/03/19 09:42

編集2016/03/26 08:01
katoy

総合スコア22328

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katoy

2016/03/26 08:02

回答に追記しました。 現時点でのタグ集計結果もリンク先で参照できます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問