ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

WWW::Mixiコミュのみんなで動くようにしようプロジェクト

  • mixiチェック
  • このエントリーをはてなブックマークに追加
現在WWW::Mixiは、mixiのデザイン大幅変更で動作しません。
そこで、少しでも動作させるようにした部分を公開していきませんか?

コメント(24)

【新規/改造】新規
【関数名】parse_post_key
【説明】書き込み用のpost_keyを取得する
【例】
$post_key = $mixi->parse_post_key();
【ソース】
sub parse_post_key {
  my $self = shift;
  my $mobile = $self->get( 'mobile_photo.pl' );
  my $res = $self->response();
  return unless ($res and $res->is_success);
  my $content = $res->content;
  return unless ($content =~ /<input name=post_key type=hidden value=(.*?)>/ );
  my $post_key= $1;
  return $post_key;
}
【新規/改造】改造
【関数名】parse_view_bbs
【説明】コミュニティの書き込みを取得
【例】
$res = $mixi->get( 'view_bbs.pl?id=29116570&comm_id=43735' );
@item = $Mixi->parse_view_bbs( $res );
【ソース】
sub parse_view_bbs {
  my $self = shift;
  my $res = (@_) ? shift : $self->response();
  return unless ($res and $res->is_success);
  my $base = $res->base->as_string;
  my $content = $res->content;
  my @items = ();
  # get topic, comments part
  my $topic_from = qq(\Q<div class="pageTitle communityTitle002">\E);
  my $topic_till = qq(\Q<div id="bbsComment">\E);

  my $comments_from = qq(\Q<dl class="commentList01">\E);
  my $comments_till = qq(\Q<div class="pageNavigation01">\E);

  my $content_topic = ($content =~ /${topic_from}(.*?)${topic_till}/s) ? $1 : return $self->log("[warn] topic part is missing.\n");

  my $content_comments = ($content =~ /${comments_from}(.*?)${comments_till}/s) ? $1 : return $self->log("[warn] comments part is missing.\n");

  # regex for parsing
  my $re_subj = '<span class="title">(.*?)<\/span>';
  my $re_time = '<span class="date">(\d{4})年(\d{2})月(\d{2})日\s*(\d{1,2}):(\d{2})';
  my $re_link = '<dt><a href="?(.+?)"?>(.*?)<\/a><\/dt>';
  my $re_imgs = '<td bgcolor="#ffffff" align="center">\s*(<table>.*?<\/table>)?';
  my $re_desc = '</dt>\n<dd>(.*?)</dd>';
  my $re_no = '<span class="senderId">(\d+)<';
  # parse topic
  my $subj = ($content_topic =~ /$re_subj/) ? $1 : return $self->log("[warn] subject is not found.\n$content_topic");
  my $time = ($content_topic =~ /$re_time/) ? sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5) : return $self->log("[warn] time is not found.\n$content_topic");
  my $link = ($content_topic =~ /$re_link/) ? $1 : return $self->log("[warn] link is not found.\n$content_topic");
  my $name = $2;
  my $imgs;
  my $desc = ($content_topic =~ /$re_desc/s) ? $1 : return $self->log("[warn] description is not found.\n$content_topic");
  ($name, $desc) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); $_; } ($name, $desc);
  my $item = { 'time' => $time,
        'description' => $desc,
        'subject' => $subj,
        'link' => $res->request->uri->as_string,
        'images' => [],
        'comments' => [],
        'name' => $name,
        'name_link' => $self->absolute_url($link, $base)};

  my @images = ($imgs =~ /<a href="javascript:void(0)" [^<>]*>.*?<\/a>/gs);
  foreach my $image (@images) {
    # parse images
    next unless ($image =~ /<a [^<>]*'show_picture.pl\?img_src=(.*?)'[^<>]*><img src=([^ ]*) border=0>/);
    push(@{$item->{'images'}}, {'link' => $self->absolute_url($1, $base), 'thumb_link' => $self->absolute_url($2, $base)});
  }

続く
続き

  # parse comments
  my @comments = ($content_comments =~ /<dt class="commentDate clearfix">(.*?)<\/dd>\n\n/gs);
  foreach my $comment (@comments) {
    unless ($comment =~ /$re_time/) { $self->log("[warn] time is not found in comment.\n$comment"); next; }
    my $time = sprintf('%04d/%02d/%02d %02d:%02d', $1,$2,$3,$4,$5);
    unless ($comment =~ /$re_link/s) { $self->log("[warn] link is not found in comment.\n$comment"); next; }
    my $link = $1;
    my $name = $2;
    my $imgs;
    unless ($comment =~ /$re_desc/s) { $self->log("[warn] desc is not found in comment.\n$comment"); next; }
    my $desc = $1;
    ($name, $desc) = map { s/[\r\n]+//g; s/<br>/\n/g; $_ = $self->rewrite($_); $_; } ($name, $desc);
    unless ($comment =~ /$re_no/s) { $self->log("[warn] no is not found in comment.\n$comment"); next; }
    my $no = $1;
    my $comment = {'time' => $time,
            'link' => $self->absolute_url($link, $base),
            'name' => $name,
            'description' => $desc,
            'no' => $no,
            'images' => []};
    my @images = ($imgs =~ /<a href="javascript:void(0)" [^<>]*>.*?<\/a>/g);
    foreach my $image (@images) {
      # parse images
      next unless ($image =~ /<a [^<>]*'show_picture.pl\?img_src=(.*?)'[^<>]*><img src=([^ ]*) border=0>/);
      push(@{$comment->{'images'}}, {'link' => $self->absolute_url($1, $base), 'thumb_link' => $self->absolute_url($2, $base)});
    }
    push(@{$item->{'comments'}}, $comment);
  }
  push(@items, $item);
  return @items;
}
> 2,3
のparse_view_bbsですが、画像の取得は行えません。
すいません、まだPerlの初歩的なことしかわからないのですが・・・
parse_view_bbs の
>  my $re_desc = '</dt>\n<dd>(.*?)</dd>';
のところ、スラッシュはエスケープする必要はないんでしょうか?
しないとダメな気がしますが、とりあえず動いていますw
>スラッシュはエスケープする必要はないんでしょうか?

自分も初心者ですが、シングルクォーテーションに囲まれて
いるからではないでしょうか?
ダブルクォーテーションだとエスケープが必要だとか…
変数に入れて使っているから、普通にスラッシュ使えます。
シングルとかダブルとか関係なく。
【新規/改造】改造
【関数名】parse_list_bookmark
【説明】お気に入りリストの取得
【備考】画像取得無し、次のページ取得無し
【例】
$res = $mixi->get( 'list_bookmark.pl' );
@item = $mixi->parse_list_bookmark( $res );
【ソース】
sub parse_list_bookmark {
 my $self = shift;
 my $res = (@_) ? shift : $self->response();
 return unless ($res and $res->is_success);
 my $base = $res->base->as_string;
 my $content = $res->content;
 my @items = ();
 # get bookmark list part
 my $content_from = qq(\Q<!-- ### friend_loop.s ### -->\E);
 my $content_till = qq(\Q<!-- ### friend_loop.e ### -->\E);
 return $self->log("[warn] bookmark list part is missing.\n") unless ($content =~ /$content_from(.*?)$content_till/s);
 $content = $1;
 # parse rows
 my $record_from = qq(\Q<table border="0" cellspacing="1" cellpadding="4" width="500">\E);
 my $record_till = qq(\Q</table>\E);
 my @records = ($content =~ /$record_from(.*?)$record_till/isg);
 return $self->log("[warn] no bookmark records found.\n") unless (@records);
 foreach my $record (@records) {
  my $item = {};
  $item->{'link'} = ($record =~/<td colspan="2" bgcolor="#FFFFFF"><a href="(.+?)">(.*?)<\/a><\/td>/) ? $1 : "";
  $item->{'name'} = $2;
  $item->{'id'} = ($item->{'link'}=~/show_friend\.pl\?id=(\d+)/) ? $1 : "";
  $item->{'subject'} = ($record =~/<td colspan="2" bgcolor="#FFFFFF" width="420">\n\n(.*?)\n\n<\/td>/) ? $1 : "";
  $item->{'lastlogin'} = ($record =~/<td bgcolor="#FFFFFF" width="250" align="left">\n(.+?)\n<\/td>/) ? $1 : "";

  push(@items, $item);
 }
 return @items;
}
【新規/改造】改造
【関数名】parse_list_community
【説明】コミュニティリスト
【備考】status取得無し、background取得無し
【例】
$res = $mixi->get( 'http://mixi.jp/list_community.pl?id=2' );
@items = $mixi->parse_list_community( $res );
【ソース】
sub parse_list_community {
 my $self = shift;
 my $res = (@_) ? shift : $self->response();
 return unless ($res and $res->is_success);
 my $base = $res->base->as_string;
 my $content = $res->content;
 my @items = ();
 my $status_backgrounds = {
  'bg_orange1-.gif' => '管理者',
 };
 # get community list part
 my $content_from = qq(\Q<!--[MessageArea]-->\E);
 my $content_till = qq(\Q<!--/[MessageArea]-->\E);
 return $self->log("[warn] community list part is missing.\n") unless ($content =~ /$content_from(.*?)$content_till/s);
 $content = $1;
 # get community list rows
 my @rows = ();
 push(@rows, [$1, $2, $3, $4, $5, $6]) while ($content =~ s/<div class="iconListImage"><a href="(.*?)" style="background: url\((.*?)\); text-indent: -9999px;" class="iconTitle" title="(.*?)">(.*?)<\/a><\/div><span>(.*?)\((\d+)\)<\/span>//is);
 return $self->log("[warn] community list has no rows.\n") unless (@rows);
 # parse each items
 foreach my $row (@rows) {
  my ($link_part, $image_part, $alt_part, $text_part, $subject_part, $num_part ) = @{$row};

  my $item = {};
  $item->{'background'} = '';
  $item->{'subject'} = $self->rewrite( $subject_part );
  $item->{'link'} = $self->absolute_url( $link_part, $base );
  $item->{'image'} = $self->absolute_url( $image_part, $base );
  $item->{'status'} = '';
  $item->{'count'} = $num_part;

  push( @items, $item );
 }
 return @items;
}
【新規/改造】改造
【関数名】parse_list_friend
【説明】マイミクシィ一覧取得
【備考】status取得無し、background取得無し
【例】
$res = $mixi->get( 'list_friend.pl?id=2' );
@items = $mixi->parse_list_friend( $res );
【ソース】
sub parse_list_friend {
 my $self = shift;
 my $res = (@_) ? shift : $self->response();
 return unless ($res and $res->is_success);
 my $base = $res->base->as_string;
 my $content = $res->content;
 my @items = ();
 # get friend list part
 my $content_from = qq(\Q<!--[MessageArea]-->\E);
 my $content_till = qq(\Q<!--/[MessageArea]-->\E);
 unless ($content =~ /$content_from(.*?)$content_till/s){
  $content_from = qq(\Q<!--[BodyMainArea]-->\E);
  $content_till = qq(\Q<!--/[BodyMainArea]-->\E);
 }
 return $self->log("[warn] friend list part is missing.\n") unless ($content =~ /$content_from(.*?)$content_till/s);
 $content = $1;
 # get friend list rows
 my @rows = ();
 push(@rows, [$1, $2, $3, $4, $5, $6]) while ( $content=~s/<div class="iconListImage"><a href="(.*?)" style="background: url\((.*?)\); text-indent: -9999px;" class="iconTitle" title="(.*?)">(.*?)<\/a><\/div><span>(.*?)\((\d+)\)<\/span>//is );

 return $self->log("[warn] friend list has no rows.\n") unless (@rows);
 # parse each items
 foreach my $row (@rows) {
  my( $link, $image, $title, $alt, $name, $count ) = @{$row};

  my $id = ($link=~m/show_friend\.pl\?id=(\d+)/) ? $1: "";

  my $item = {};
  $item->{'background'} = '';
  $item->{'subject'} = $self->rewrite( $name );
  $item->{'link'} = $self->absolute_url( $link, $base );
  $item->{'image'} = $self->absolute_url( $image, $base );
  $item->{'status'} = '';
  $item->{'count'} = $count;

  push( @items, $item );
 }
 return @items;
}
【新規/改造】改造
【関数名】parse_standard_history_next
【説明】次のページ取得
【備考】subject取得無し、list_friendとlist_communityで動作確認済み
【例】
$url = 'list_friend.pl?id=2';
while( $url ne '' ){
 $res = $mixi->get( $url );
 push(@items, $mixi->parse_list_friend( $res ) );
 $next = $mixi->parse_standard_history_next( $res );
 $url = $next->{'link'};
}
【ソース】
sub parse_standard_history_next {
 my $self = shift;
 my $res = (@_) ? shift : $self->response();
 return unless ($res and $res->is_success);
 my $base = $res->base->as_string;
 my $content = $res->content;
 return unless ($content =~ /<\/li><li><a href="(.*?)">次を表示<\/a><\/li><\/ul>/);
 my $link = $self->absolute_url($1, $base);
 my $next = {'link' => $link };
 return $next;
}
もうアップしないと言った割には。

【新規/改造】改造
【関数名】parse_show_log
【説明】足あと解析
【備考】去年の足あと、動作未確認
【例】
$res = $mixi->get( 'show_log.pl' );
@items = $mixi->parse_show_log( $res );
$res = $mixi->get( 'show_log.pl?page=2' );
push( @items, $mixi->parse_show_log( $res ) );
【ソース】
1.「use Time::Local;」する。
# use Jcode;
use LWP::Debug ();
use HTTP::Cookies;
use HTTP::Request::Common;
use Time::Local;

sub new {
  my ($class, $email, $password, %opt) = @_;
  my $base = 'http://mixi.jp/';

2.parse_show_log
sub parse_show_log {
  my $self = shift;
  my $res = (@_) ? shift : $self->response();
  return unless ($res and $res->is_success);
  my $base = $res->base->as_string;
  my $content = $res->content;

  my( $sec, $min, $hour, $mday, $mon, $year ) =
    ( localtime( time ) )[0,1,2,3,4,5];
  $year += 1900;
  $mon += 1;
  my $olddate = time;

  my @items = ();
  my $re_date = '(\d{2})月(\d{2})日 (\d{1,2}):(\d{2})';
  my $re_link = '<a href="?(.+?)"?>(.+?)<\/a>';
  # get log part
  my $content_from = qq(\Q<div class="logListCenter">\E);
  my $content_till = qq(\Q<!--/\.logListCenter01--></div>\E);
  return $self->log("[warn] log part is missing.\n") unless ($content =~ /$content_from(.*?)$content_till/s);
  $content = $1;
  # parse main menu items
  my @lines = ($content =~ /<li\b[^<>]*>(.*?)<\/li>/gs);
  return $self->log("[warn] no log found in log part.\n") unless (@lines);
  # parse each items
  foreach my $line (@lines) {
    $line =~ /${re_date}<\/span><span class="name"><a href="(.*?)">(.*?)<\/a>/ or return $self->log("[warn] a tag, date or name in not found in '$line'.\n" );
    $mon = $1;
    $mday = $2;
    $hour = $3;
    $min = $4;
    my $ndate = &timelocal( 0, $min, $hour, $mday, $mon-1, $year );
    if( $ndate > $olddate ){
      $year --;
      $olddate = &timelocal( 0, $min, $hour, $mday, $mon-1, $year )
    } else {
      $olddate = $ndate;
    }
    my $time = sprintf('%04d/%02d/%02d %02d:%02d', $year, $mon, $mday, $hour, $min );
    my $link = $self->absolute_url( $5, $base );
    my $name = $self->rewrite( $6 );
    my $mymixi = 0;
    if( $line =~m/\/log_mymixi\.gif"\// ){
      $mymixi = 1;
    }
    my $id = ($link=~m/\?id=(\d+)/) ? $1 : '';

    push(@items, {'time' => $time, 'name' => $name, 'link' => $link, 'mymixi'=>$mymixi, 'id'=>$id });
  }
  return @items;
}
もう、殆ど誰も使わなくなっていると思いますが、
まずは、正常にログインできるようにしてみました。

【新規/改造】改造
【関数名】login、session、stamp
【説明】クッキーの名称が変わったのでログインでるようにクッキーの名称を変更
【備考】
【例】
【ソース】

% diff -u -0 Mixi.pm-bck Mixi.pm
--- Mixi.pm-bck 2007-08-01 14:38:45.000000000 +0900
+++ Mixi.pm 2012-09-06 00:18:19.178000000 +0900
@@ -52 +52 @@
- my $page = 'login.pl';
+ my $page = 'login.pl?from=login0';
@@ -97 +97 @@
- $self->cookie_jar->set_cookie(undef, 'BF_SESSION', $session, '/', 'mixi.jp', undef, 1, undef, undef, 1);
+ $self->cookie_jar->set_cookie(undef, 'session', $session, '/', 'mixi.jp', undef, 1, undef, undef, 1);
@@ -100 +100 @@
- return ($self->cookie_jar->as_string =~ /\bSet-Cookie.*?:.*? BF_SESSION=(.*?);/) ? $1 : undef;
+ return ($self->cookie_jar->as_string =~ /\bSet-Cookie.*?:.*? session=(.*?);/) ? $1 : undef;
@@ -108 +108 @@
- $self->cookie_jar->set_cookie(undef, 'BF_STAMP', $stamp, '/', 'mixi.jp', undef, 1, undef, undef, 1);
+ $self->cookie_jar->set_cookie(undef, 'stamp', $stamp, '/', 'mixi.jp', undef, 1, undef, undef, 1);
@@ -111 +111 @@
- return ($self->cookie_jar->as_string =~ /\bSet-Cookie.*?:.*? BF_STAMP=(.*?);/) ? $1 : undef;
+ return ($self->cookie_jar->as_string =~ /\bSet-Cookie.*?:.*? stamp=(.*?);/) ? $1 : undef;

ちなみに、githubにも入っています。作者は、更新しなくなっているので、
これをみんなで更新して行けば良いのでは?

https://github.com/gitpan/WWW-Mixi
こんにちは。
1時間ほど前から突然ログインできなくなっちゃったのですが、何かmixiの仕様が変わったのでしょうか? みのさんの19の改造は加えました。
すみません。またアクセスできるようになりました。
動かない原因を調べようと、Mixi.pmのログイン処理をシミュレートして自分でプログラム書いてたら、いつの間にか元のmixi.pmでもログインできるようになってました。
お騒がせしました。

でも今度はログインフォームが出ずに、いきなりhome.plが表示される・・・・
支障は無いのだけど。。。。

もうちょっと調べますm(_ _)m
また唐突にログインできなくなりました。。。。何なんだろう? IPアドレス変えてみたり、家族のid使ってみても入れないし。頻繁すぎるアクセスで規制が掛かる場合は、そういうメッセージが表示されますしね。

とりあえず何時間か待ってみます。
>>[23]

私はTkMixiViewerというAndroid用mixiビューアの作者で、WWW::Mixi については何も知りませんが、mixiのログインについて少し知っていることを書きます。

2012/7/17頃にログイン周りの仕様変更があり、いわゆる CSRF 対策のようなものが 14:00〜15:00 くらいの時間帯に実施されています。
具体的にはログイン画面の hidden の post_key 値を POST しないとログインできません。

お困りの事象とは別件かもしれませんが(あるいは対策済みかもしれませんが)参考まで。

ログインすると、残り3件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

WWW::Mixi 更新情報

WWW::Mixiのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。