ハブポストの記事評価に触発され、同様の記事を作成することを決めましたが、ハブ自体の評価を作成することにしました。
記事の前半では、ハブと企業の評価、およびそれらの小さな分析を紹介します。 そして2つ目-JSoupライブラリを使用してJavaでHabraのHTMLページをどのように解析したか、どのような興味深い現象や問題に遭遇したかについて詳しく説明します。 そして、記事の最後に、プログラムの完全なソースコードを示します。
Webページとしての4つの評価(すべて)
ハブの評価
投稿数別
クローゼット 35 971
私はPR 5 461です
Web開発 4 011
情報セキュリティ 3 385
Google 2,770
アイロン 2 733
ガジェット ブーム用デバイス 2,375
プログラミング 2,293
Linux 2 235
Android 1 965
JavaScript 1 687
アップル 1,612
ハブラハブル 1 568
.NET 1,485
PHP 1 465
システム管理 1,454
DIYまたはDIY 1 442
開発 1 331
プロジェクト管理 1,261
インターフェイス 1 257
マイクロソフト 1 237
ゲーム開発 1 218
オープンソース 1 110
スマートフォンとコミュニケーター 1,091
JAVA 1,020
IT 996での 設計
アルゴリズム 991
著作権 982
ソーシャルネットワークとコミュニティ 949
GTD 939
Windows 919
IT 916 の教育プロセス
Python 866
ロボット 798
Android 783 用の開発
iOS 777の 開発
ホスティング 749
C ++ 711
立法とITビジネス新規 677
メディア 664
(...)
Tumblr 3
カブリッド 3
産業用プログラミングの新しい 3
ジュリア新 2
Microsoft Access 2
グロースハッキングnew 2
Google Checkout 0
マイスペース 0
Xcode新規 0
SCADA new 0
私はPR 5 461です
Web開発 4 011
情報セキュリティ 3 385
Google 2,770
アイロン 2 733
ガジェット ブーム用デバイス 2,375
プログラミング 2,293
Linux 2 235
Android 1 965
JavaScript 1 687
アップル 1,612
ハブラハブル 1 568
.NET 1,485
PHP 1 465
システム管理 1,454
DIYまたはDIY 1 442
開発 1 331
プロジェクト管理 1,261
インターフェイス 1 257
マイクロソフト 1 237
ゲーム開発 1 218
オープンソース 1 110
スマートフォンとコミュニケーター 1,091
JAVA 1,020
IT 996での 設計
アルゴリズム 991
著作権 982
ソーシャルネットワークとコミュニティ 949
GTD 939
Windows 919
IT 916 の教育プロセス
Python 866
ロボット 798
Android 783 用の開発
iOS 777の 開発
ホスティング 749
C ++ 711
立法とITビジネス新規 677
メディア 664
(...)
Tumblr 3
カブリッド 3
産業用プログラミングの新しい 3
ジュリア新 2
Microsoft Access 2
グロースハッキングnew 2
Google Checkout 0
マイスペース 0
Xcode新規 0
SCADA new 0
加入者数別
クローゼット 124 521
私はPR 101 864です
Web開発 96 117
Android 95 361
ガジェット ブーム用デバイス 95 020
スマートフォンとコミュニケーター 94,376
Google 93 844
DIYまたはDIY 92322
鉄 91 959
情報セキュリティ 91 729
Linux 91 103
ロボット 89 721
プログラミング 89,668
タブレット 88 757
Google Chrome 88 197
オペレーティングシステム 88 098
インターフェース 88 064
Windows 87 695
iPhone 87 609
アルゴリズム 87 372
Webデザイン 87 341
電子書籍 86 582
IT 86 266での 設計
完璧なコード 85 525
ブラウザ 85 443
iPad 85 290
エネルギーとバッテリー 84 866
ポピュラーサイエンス 84,668
PHP 84 621
(...)
バックアップ 3 3 503
Xcode New 2 823
Physics new 2 372
Raspberry Pi new 2 274
産業用プログラミングnew 2 141
電子商取引の新しい開発 2 034
SCADA new 1 856
Laravel new 1,799
グロースハッキング新規 1,063
ジュリアニュー 948
私はPR 101 864です
Web開発 96 117
Android 95 361
ガジェット ブーム用デバイス 95 020
スマートフォンとコミュニケーター 94,376
Google 93 844
DIYまたはDIY 92322
鉄 91 959
情報セキュリティ 91 729
Linux 91 103
ロボット 89 721
プログラミング 89,668
タブレット 88 757
Google Chrome 88 197
オペレーティングシステム 88 098
インターフェース 88 064
Windows 87 695
iPhone 87 609
アルゴリズム 87 372
Webデザイン 87 341
電子書籍 86 582
IT 86 266での 設計
完璧なコード 85 525
ブラウザ 85 443
iPad 85 290
エネルギーとバッテリー 84 866
ポピュラーサイエンス 84,668
PHP 84 621
(...)
バックアップ 3 3 503
Xcode New 2 823
Physics new 2 372
Raspberry Pi new 2 274
産業用プログラミングnew 2 141
電子商取引の新しい開発 2 034
SCADA new 1 856
Laravel new 1,799
グロースハッキング新規 1,063
ジュリアニュー 948
ハブを並べ替えると、興味深いものが現れました。 たとえば、ポストがゼロのハブがあることは知りませんでした。 そして、それらの4がありました ! さらに、 500人以上がそれぞれに加入しています。
3つのハブ- 私はPRとWeb開発である Chulanは 、投稿数と読者数の点でリーダーです。 管理者が記事を削除するため、クローゼットは1位です。 次は、ハブで非常に人気のある情報セキュリティです。
残念ながら、 Habrahabrハブがオフトピックである理由を理解できませんでした。 投稿数で、彼は13位になり、彼のサブスクライバーは80Kを超えます。 同じサイトについてサイトに書くことは、トピックからの逸脱ですか?
Javaハブが私たちが望むほど高くないのは残念でした。
格付け会社
当初はハブに対してのみ評価を作成する予定でしたが、記事へのコメントの中で、彼らは企業に対しても同じことをするという良いアイデアを提示しました。 コードをあまり変更する必要はありませんでした。多くの企業があります-1343。したがって、TOP-30と最後の10社のみを掲載します。 これは興味深い点です-何らかの理由で、HabrtはEverything(1331)を表示しますが、私のプログラムでは1343をカウントしていますが、実際、これは正しいです。 それらを手動で数えると-ページ数67に20の会社、さらには3を掛けると-1343になります。
加入者数別
ヤンデックス 11 056
Google 10,999
Microsoft 6 797
Intel 5 463
アップル 4 124
OperaソフトウェアASA 3 873
ハッカーマガジン 3 034
ズフォートグループ 2 969
JetBrains 2 946
Mail.Ru Group 2 921
VimpelCom(ビーライン) 2 730
IBM 2 655
Artemy Lebedev Studio 2 640
ノキア 2,542
TM 2 314
シンプルサイエンス 2,222
サムスン 2 222
2GIS 1 992
アドビ 1 878
ABBYY 1 847
ボックスの概要 1 844
VKontakte 1 841
HP 1 828
モシグラ 1,772
Skype 1 718
カスペルスキーラボ 1,667
ASUSロシア 1,615
ソニーモバイルコミュニケーションズ 1,572
Apps4All 1,541
リングアレオ 1,493
(...)
アンジー 5
フォトプレイ 5
Florist.ru 5
PlatOn 5
ポリビゾール 5
ダルトンメディアLLC 5
bdlプレミアム 4
GolovachCourses 4
タイムラ株式会社 4
Slon.ru 3
Google 10,999
Microsoft 6 797
Intel 5 463
アップル 4 124
OperaソフトウェアASA 3 873
ハッカーマガジン 3 034
ズフォートグループ 2 969
JetBrains 2 946
Mail.Ru Group 2 921
VimpelCom(ビーライン) 2 730
IBM 2 655
Artemy Lebedev Studio 2 640
ノキア 2,542
TM 2 314
シンプルサイエンス 2,222
サムスン 2 222
2GIS 1 992
アドビ 1 878
ABBYY 1 847
ボックスの概要 1 844
VKontakte 1 841
HP 1 828
モシグラ 1,772
Skype 1 718
カスペルスキーラボ 1,667
ASUSロシア 1,615
ソニーモバイルコミュニケーションズ 1,572
Apps4All 1,541
リングアレオ 1,493
(...)
アンジー 5
フォトプレイ 5
Florist.ru 5
PlatOn 5
ポリビゾール 5
ダルトンメディアLLC 5
bdlプレミアム 4
GolovachCourses 4
タイムラ株式会社 4
Slon.ru 3
投稿数別
ヤンデックス 1 012
マイクロソフト 828
Intel 491
Google 422
Mail.Ru Group 317
Apps4All 292
Opera Software ASA 234
サムスン 215
ASUSロシア 209
ESET NOD32 200
ABBYY 197
IBM 190
HP 188
Evernote 186
Webnames.ru 169
MUK 154
ノキア 142
Zfort Group 134
ポジティブテクノロジー 131
シンプルサイエンス 127
EPAM Systems 127
ソニーモバイルコミュニケーションズ 116
CROC 115
ターボミルク 103
セレクター 101
REG.RU 97
ボックスの概要 96
チクルム 96
SmartGadget 94
ジェットブレイン 87
(...)
HotSupport -2
ワークセクション -2
次へ -2
MFIソフト -2
NVIDIA Corporation -2
DeepArtment -2
RuTube -2
最重要指名手配電話 -3
「スタジオ-8812」 -3
590.com.ua -3
マイクロソフト 828
Intel 491
Google 422
Mail.Ru Group 317
Apps4All 292
Opera Software ASA 234
サムスン 215
ASUSロシア 209
ESET NOD32 200
ABBYY 197
IBM 190
HP 188
Evernote 186
Webnames.ru 169
MUK 154
ノキア 142
Zfort Group 134
ポジティブテクノロジー 131
シンプルサイエンス 127
EPAM Systems 127
ソニーモバイルコミュニケーションズ 116
CROC 115
ターボミルク 103
セレクター 101
REG.RU 97
ボックスの概要 96
チクルム 96
SmartGadget 94
ジェットブレイン 87
(...)
HotSupport -2
ワークセクション -2
次へ -2
MFIソフト -2
NVIDIA Corporation -2
DeepArtment -2
RuTube -2
最重要指名手配電話 -3
「スタジオ-8812」 -3
590.com.ua -3
そもそも、「会社が非アクティブ化されている」と「ページが見つからない」という2種類の会社不在があることに驚いた。 繰り返しますが、すべての企業がリストから選ばれました。 投稿数-2でマークした最初のビュー。 そのような会社はたくさんあります。 また、名前が数字で構成されている3つの企業は、「ページが見つかりません」につながります。 -3とマークしました。 そのようなものです。 また、投稿がゼロの企業も多数あります(例: Apple) 。 なぜ会社のアカウントを作成し、そこからまったく書かないのだろうか?
実際、ハブに登録された1343から、存在しない企業や投稿のない企業を削除すると、321のみになります。そのようなことがあります。
開発
非常に長い間、私はHabrahabr Apiを理解しようとしました 。 判明したように、それは閉じられており、まだ開発中です。 しかし、 support @ habrahabr.ruとの通信で、彼らは自分のページを解析することに何もしないと私に言った。 実際、これはまさにAndroid向けのhabraclientの動作方法です(現時点では)。「自分用」のプロジェクトになると、大好きなJavaを選択します。 彼女は今回も私を失望させませんでした-JSoupライブラリにより、HTMLページから必要なデータを数行で取得できました。 しかし、まずハブがどのように機能するかを説明しましょう。
ハブのあるページはhabrahabr.ru/hubs/pageN/にあります。ここで、Nは1以降の数字です。 したがって、すべてのハブの完全なリストを取得したい場合は、これらのページがダウンロードされるまで、それらが終了するまで分析する必要があります。 各ページにハブのリストがあります。 リストアイテムの形式は非常にシンプルで、解析が容易です。 次のようになります。
<div class="hub " id="hub_50"> <div class="habraindex">1 280,58</div> <div class="info"> <div class="title"> <a href="http://habrahabr.ru/hub/infosecurity/"> </a> <span class="profiled_hub" title=" "></span> </div> <div class="buttons"> <input type="button" class="mini blue subscribeHub" value="" data-id="50"> <input type="button" class="mini hidden unsubscribeHub" value="" data-id="50" "=""> </div> <div class="clear"></div> <div class="stat"><a href="http://habrahabr.ru/hub/infosecurity/subscribers/" class="members_count">91741 </a>, <a href="http://habrahabr.ru/hub/infosecurity/posts/">3385 </a><a></a></div><a> </a></div><a> </a></div>
サイト上のすべてのハブのリストを返すメソッドを作成しましょう。
static List<Hub> getAllHubs() { ArrayList<Hub> fullHubsList = new ArrayList<>(); String urlHubsIncomplete = "http://habrahabr.ru/hubs/page"; int pageNum = 1; do { String urlHubs = urlHubsIncomplete + pageNum; try { Document doc = Jsoup.connect(urlHubs).get(); Elements hubs = doc.select(".hub"); if (hubs.size() == 0) { break; } for (Element hubElem : hubs) { Hub hub = new Hub(hubElem); fullHubsList.add(hub); } pageNum++; } catch (Exception e) { e.printStackTrace(); break; } } while (true); return fullHubsList; }
無限のwhileループをスピンし、反復ごとに新しいURLを形成します。 次に、 Jsoup.connect(urlHubs).get()を使用して、ハブとそのパラメーターのリストを含むHTMLドキュメントを直接取得します。 ご覧のとおり、ハブ情報ハブにはハブクラスがあり、 doc.select( "。Hub")を呼び出すことにより、これらの要素のリストを取得します。 サイズがゼロの場合、つまり、最後のページを通過し、すべてのハブを既に分析したことを意味します。その後、ループを終了します。
次に、すべてのハブ要素を調べ 、それぞれに対してタイプハブのオブジェクトを作成し、 org.jsoup.nodes.Elementをコンストラクターに渡します。 上記と同じ形式のHTMLコードが含まれています。 では、すべてから抽象化しましょう 。 このために、OOPが存在します。 上記のHTMLの一部と、それを詰め込む必要のあるクラスだけが私たちの前にあります。 クラスのフレームワークを書きましょう:
import org.jsoup.nodes.Element; public class Hub { String title; int posts; boolean profiled; int membersCount; float habraindex; String url; public Hub(Element hubElem) { } }
コンストラクタを書きましょう。 始めるために、最も簡単なことをしましょう-ヘッダータグからデータを取得します。 これを行うには、まずフォームのdiv自体を抽出します
<div class="title"> <a href="http://habrahabr.ru/hub/infosecurity/"> </a> <span class="profiled_hub" title=" "></span> </div>
パーシムスルー
Element titleDiv = hubElem.select(".title").get(0); Element tagA = titleDiv.getElementsByTag("a").get(0); title = tagA.text(); url = tagA.attr("href"); profiled = (hubElem.select(".profiled_hub").size() != 0);
次に、サブスクライバーと投稿の数、実際には並べ替えに使用するパラメーターを解析します。 しかし、すぐに最初の問題に遭遇します-タグには文字列"91741 subscribers"が含まれていますが、これを取得して整数に変換することはできません-文字が含まれています! ここでは、 正規表現が役立ちます。 文字列を受け取り、数値以外のすべてを切り取り、さらに結果をintに変換する巧妙なメソッドをすばやく作成します。 \ Dは数字ではありませんが、 + -"1回以上発生します。" つまり この場合、文字をvoidに置き換えています。
private int getNumbers(String str) { String numbers = str.replaceAll("\\D+", ""); return Integer.valueOf(numbers); }
これで、冷静な精神ですでに価値を得ることができます。
String membersCountFullStr = hubElem.select(".members_count").get(0).text(); membersCount = getNumbers(membersCountFullStr); String statFullStr = hubElem.select(".stat").get(0).getAllElements().get(2).text(); posts = getNumbers(statFullStr);
原則として、これは停止できますが、興味のために、ハブに関するすべての可能な情報を抽出することにしました。 ここで、非常に興味深い2番目の問題が発生しました。これは、記事のハイライトです 。 Habraindexを解析する方法は?
まず、コンマをピリオドに置き換え、余分なスペースを削除する必要があります。 しかし、それだけでは十分ではありません! Habraindexをコピーしてコードに貼り付けると、パーサーは引き続きエラーを返します-Double.valueOf( "-1.11") 。 そして、同じ番号を手動で入力した場合-すべてがOKです。 そして、私のIDEAでは視覚的にはまったく同じに見えます!
habraのデザイナーは、 マイナスではなくダッシュを使用しただけで、異なる文字コードを使用していること、そしてもちろん、パーサーを食べないことがわかりました。 注意してください。 問題の本質は次のとおりです。
System.out.println((int)'-');//45 System.out.println((int)'–');//8211
かつて、私の記事Tricky Java Tasksで、 Lが小さい1と区別できない場合のキャッチを調べました。実際、今、私は同様の問題に遭遇しました。
したがって、Habraindexを取得するためのコードはもう少し複雑になります。
String rawHabraIndex = hubElem.select(".habraindex").get(0).text();//1 265,92 char minus = 45;//'-' char dash = 8211;//'–' String niceHabraIndex = rawHabraIndex.replaceAll(" ", "").replace(",", ".").replace(dash,minus);//1266.72 habraindex = Float.valueOf(niceHabraIndex);
次に、ハブのネストされた静的クラスとしてポストコンパレーターを記述します
public static class ComparePosts implements Comparator<Hub> { @Override public int compare(Hub o1, Hub o2) { return o2.posts - o1.posts; } }
メインのどこかに並べ替えます
List<Hub> hubs = getAllHubs(); Collections.sort(hubs, new Hub.ComparePosts());
すべて、タスクが完了しました! 加入者の数は似ています。 次に、コンソールに2つのリストを表示するコードを作成し、記事にすぐに挿入できるようにしました。最初にそれを行いました。
すべてのハブを取得するには約10秒かかります。 ソースコードはこちらからダウンロードできます 。 Jsoupをインストールし、パスを自分のものに置き換えることを忘れずに、次のようにビルドして実行します。
javac -cp .;"C:\prog\lib\jsoup-1.7.3.jar" com/kciray/habrahubs/Main.java java -cp .;"C:\prog\lib\jsoup-1.7.3.jar" com.kciray.habrahubs.Main
さらに、同じクラスを再編集して、企業に関する統計を収集しました。 そこには、すべてが似ているように見えますが、会社のブログの投稿数を調べるには、それぞれ個別にページをロードする必要がありました。これには約5分かかりました。 速度を上げるためにマルチスレッドダウンロードを行いました。 habraでは、同時に5〜7ページ以上をロードできないことがわかりました。 実際、 ArrayList <CompanyBlog>をシリアル化し 、書き留めました。 この100キロバイトのファイルは2番目のソースにあります-作業できます。
完全な評価とよりコンパクトな形式に興味がある場合は、Webページとして投稿しました 。