ホームページ  >  記事  >  ウェブフロントエンド  >  V2EX フォーラム クライアント投稿情報のクローリング (1)_html/css_WEB-ITnose

V2EX フォーラム クライアント投稿情報のクローリング (1)_html/css_WEB-ITnose

WBOY
WBOYオリジナル
2016-06-21 08:58:011626ブラウズ

はじめに

私は V2EX に頻繁にアクセスするので、空き時間を利用して Android クライアントを作成することにしました。オープンソースはここ https://github.com/ihgoo です。 /V2EX

仕事をうまくやり遂げたい場合は、まずツールを強化する必要があります。プロジェクト全体は Gradle で構築され、Android Studio によって開発されます。

会社のプロジェクトも Android Studio に移行しました。Studio には、変数を入力するときに、最初に変数のスペルを覚えていない場合に特に気に入っている機能があります。後で自動的にプロンプ​​トが表示されます。プラグインも多数あり、ビジネスロジックのみに重点を置いて開発がより確実なものになってきています。

業務に応じてモジュールに分割

フォーラムクライアントはビジネスロジックに応じて以下のモジュールに分割

  • 非言語での閲覧モジュール・ログイン状態

    • 投稿一覧閲覧
    • 投稿詳細閲覧
  • ユーザーモジュール

    • ログインモジュール
    • ユーザー情報モジュール
  • ログイン状態モジュール

    • ログイン状態返信、投稿詳細閲覧
    • 収集していいね
    • 返信リマインダー

依存関係

依存関係ライブラリはネイティブ コントロールと成熟したフレームワークの使用を検討します

compile 'com.jakewharton:butterknife:6.1.0'    compile 'com.squareup.retrofit:retrofit:1.9.0'compile 'com.squareup:otto:+'compile 'com.facebook.fresco:fresco:0.1.0+'compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'compile 'com.squareup.okhttp:okhttp:2.0.0'

butterknife: jack master によって書かれた Ioc フレームワーク。dagger に相当します。idea/studio にはバターナイフをサポートするプラグインがあり、ワンクリックで findviewbyid を見つけられます。

レトロフィット: 強力なネットワーク リクエスト ライブラリ。

fresco: 画像ライブラリをロードします。これを使用する前は、常に Imageloader を使用していました。プロジェクト内で画像の gif とプログレッシブ表示をサポートする必要があるため、これを使用します。

オットー:eventBus フレームワーク!アーティファクトを切り離すことで、すべてがよりシンプルになります。

プロジェクトをビルドし、パッケージ構造を整理します

パッケージ構造は次のとおりです:

app: アプリのアプリケーションについて、など。

client: ネットワークリクエストヘッダーの定義、ネットワークリクエストライブラリの設定など。

core: 基本フレームワーク、mvc 構造の c に相当します。 もちろん、ここでの c は、Controller

model: モデル層

paser: 解析層を指します。 json であっても html であっても、エンティティ クラスはこの分析層によって生成されます。

永続性: 定数クラス、データベース フィールド、インターネット リクエスト フィールド、アプリ構成フィールドなどを配置します。

ui: プレゼンテーション層を表示します。

utils: いくつかの便利なツール クラス

プロジェクトは Gradle でビルドされ、アプリはモジュールとして使用され、他のモジュールはマウントとしてアプリにマウントされます。他のモジュールをすぐに置き換えることができ、ソース コードを変更できること (aar 形式でインポートされたソース コードは変更できません)。

APIについて

公式json APIの呼び出し回数に制限があるため、htmlページの解析を検討しました。

コンピュータ側の HTML が大きすぎるため、電力を節約し、アプリが占有するリソースを削減するために、WAP 側のページをモバイルとして偽装できます。ここでは、HTML を解析するために

を使用します。これは、Python の pyquery に相当し、サポートされています。必要なリソースを取得するための Jqery のようなセレクター メソッド。シンプルで便利ですが、非常に粗雑です。唯一の欠点は、ページ内の一部の要素が ajax 形式で形成されている場合、httpunit を使用できますが、Web ページを実行するためにブラウザー カーネルを起動する必要があるため、混乱が生じることです。 Web ページの作成が完了したら、情報を取得します。
public class ApiHeaders implements RequestInterceptor {    private String sessionId;    public void setSessionId(String sessionId) {        this.sessionId = sessionId;    }    public void clearSessionId() {        sessionId = null;    }    @Override public void intercept(RequestFacade request) {        request.addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19");        request.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");        if (sessionId != null) {        }    }}

投稿リストを解析します

投稿リスト内のこれらのデータの解析には注意する必要があります

アバター 著者 アバター
  • ノード ノード名
  • タイトル title
  • スモールフェード (時間) 出版時刻
  • スモールフェード 著者 著者名
  • count_livid 返信数 以下はコードですjsoup を使用して解析され、解析されました。 成功すると、エンティティ クラス ForumItemBean に詰め込まれ、コレクションの形式で listView のアダプターに返されます。
  • public class PaserFourmList {    public static ArrayList<ForumItemBean> paser2ForumItem(String string) {        Document document = Jsoup.parse(string);        Elements elements = document.select(".cell").select(".item");        ArrayList<ForumItemBean> list = new ArrayList<>();        for (Element element : elements) {            // avatar            // node            // title            // small fade (time)            // small fade author            // count_livid            String avatar = element.select(".avatar").first().attr("src");            String node = element.select(".node").first().html();            String username = element.select(".small > strong").first().text();            String countLivid = element.getElementsByClass("count_livid").text();            String time = element.select(".small").select(".fade").get(1).text();            String href = element.getElementsByClass("item_title").html();            if (href.length()!=0){                href = href.substring(12, href.indexOf("#"));            }            int indexOf = time.indexOf("前");            if (indexOf != -1) {                time = time.substring(0, indexOf);            }            ForumItemBean forumItemBean = new ForumItemBean();            Member member = new Member();            member.setAvatarMini(avatar);            member.setUsername(username);            forumItemBean.setId(Misc.parseInt(href, 0));            forumItemBean.setMember(member);            forumItemBean.setLastTime(time);            forumItemBean.setReplies(Misc.parseInt(countLivid, 0));            forumItemBean.setTitle(element.select(".item_title").first().select("[href]").html());            list.add(forumItemBean);        }        return list;    }}
  • Jsoup を使用するときに遭遇する落とし穴

jsoup を使用する場合 このクラスのように 77b5d516149a057bad6c85e8721f29b7 にスペースがある場合は、element.select(".content").select(".type") を使用する必要があります。解析してください。element.select (".content type") を解析できません。

#d1dea21e92cc4b986367cc32d8e4278f もあります。このようなものは element.select(".content-type") を使用して解析できません。 getElementsByClass(( "コンテンツ タイプ").

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。