HTML内の文字列の出現数を数える。
設計書ばかりと睨めっこしていたら、気分が悪くなってきたので、気晴らしにプログラムを書きました。かなり汚いプログラムだけど、さらしておきます。先人たちの知恵も入っているので、参照元を記述したいところですが、かなり昔のプログラムを寄せ集めたので、忘れてしまっています。思い出したら、参照元を記述します。といっても、基本ロジックだけですが。エラー制御とかは、無視しているので、万が一、使用したいという奇特な方は、自己責任でご使用ください。
処理の内容は、urlから、htmlを拾ってきて、mecabを使って名詞をカウントしています。本来なら、html parserとかで、タグを消すのが美しいのだろうけど、適当なライブラリが見つからなかったため、ごっちゃでカウント。
hoge.cpp
#include <string> #include <iostream> #include <algorithm> #include <map> #include <vector> #include <iterator> #include "curl/curl.h" #include "mecab.h" #define CHECK(eval) if (! eval) { \ const char *e = tagger ? tagger->what() : MeCab::getTaggerError(); \ std::cerr << "Exception:" << e << std::endl; \ delete tagger; \ return -1; } static std::string buffer; static int writer(char *data, size_t size, size_t nmemb, std::string *writerData) { int result = 0; if (writerData != NULL) { buffer->append(data, size * nmemb); result = size * nmemb; } return result; } std::string getHtml(const std::string url) { CURL *curl; CURLcode result; curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_HEADER, 0); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer); result = curl_easy_perform(curl); curl_easy_cleanup(curl); if (result == CURLE_OK) return buffer; else return NULL; } } int parse_mecab(const std::string article, std::map<std::string, int>& v) { std::string tmp; MeCab::Tagger *tagger = MeCab::createTagger(""); CHECK(tagger); const MeCab::Node* node = tagger->parseToNode(article.c_str()); CHECK(node); for (; node; node = node->next) { // 名詞のみ。ただし、記号と、数字は、除外 if(node->posid >= 36 && node->posid <= 67 && node->posid != 36 && node->posid != 48) { tmp = std::string((const char*)node->surface, node->length); v[tmp]++; } } delete tagger; return 0; } bool greater_count(const std::pair<std::string, int>& x, const std::pair<std::string, int>& y) { return x.second > y.second; } int main(int argc, char* argv[]) { std::map<std::string, int> v; if (argc < 1) return -1; const std::string html = getHtml(std::string(argv[1])); int rc = parse_mecab(html, v); std::vector<std::pair<std::string, int> > tmp(v.begin(), v.end()); std::sort(tmp.begin(), tmp.end(), greater_count); std::vector<std::pair<std::string, int> >::iterator i = tmp.begin(); for (; i != tmp.end(); ++i) std::cout << i->first << ":" << i->second << std::endl; return 0; }
コンパイルは、
$ g++ `curl-config --cflags` `mecab-config --cflags` `curl-config --libs` `mecab-config --libs` hoge.cpp
で、どぞ。
使い方は、
$ ./a.out http://www.yahoo.co.jp
;-P