ishiducaの日記 このページをアンテナに追加 RSSフィード

2010-04-10

[][Web::Scraper][Webスクレイピング]pixivのお気に入りリストを抽出するスクリプトを直した 22:41 [Web::Scraper][Webスクレイピング]pixivのお気に入りリストを抽出するスクリプトを直した - ishiducaの日記 を含むブックマーク はてなブックマーク - [Web::Scraper][Webスクレイピング]pixivのお気に入りリストを抽出するスクリプトを直した - ishiducaの日記 [Web::Scraper][Webスクレイピング]pixivのお気に入りリストを抽出するスクリプトを直した - ishiducaの日記 のブックマークコメント

WWW::Mechanizeを使ってpixivへログインして、ごにょごにょする」がうまく作動してなかったようなので直した。変わったといっても

  • 文字コードが euc_jp から utf-8 になってた
  • ログイン時の引数に mode が追加されていた

くらいだけど。

pixiv2pl

#!/usr/bin/perl
use strict;
use warnings;
use Encode;
use WWW::Mechanize;
use Web::Scraper;

my $enc_utf8 = find_encoding('utf-8');

my $home = 'http://www.pixiv.net/';
my $mech = new WWW::Mechanize( autocheck => 1 );
$mech->get($home);
# my_userid,my_passwordは自分のを使ってね
$mech->submit_form(
    form_number => 2,
    fields => {
        'mode'     => 'login',
        'pixiv_id' => 'my_userid',
        'pass'     => 'my_password',
    },
);

my $scraper = scraper {
    process "#illust_c5", 'lists' => scraper {
        process "li", 'li[]' => scraper {
            process "a",   'link'    => '@href';
            process "img", 'image'   => '@src';
            process "div", 'comment' => 'TEXT';
        };
    };
};

(my $temp =<<"TEMP") =~ tr/\n//d;
<div>
<a href="${home}%%LINK%%">
<img src="%%SRC%%" border="0" /></a>
<div>%%COM%%</div></div>
TEMP
;

if ($ENV{'GATEWAY_INTERFACE'}) {
    require CGI;
    print CGI::header('text/html; charset=utf-8');
}
print <<'HTML';
<!doctype html>
<html>
<head>
<meta charset='utf-8' />
<title>pixiv::myfavorite</title>
<head>
<body>
HTML
;

for (my $i = 1; $i <= 20; $i++) {
    $mech->get("${home}bookmark_new_illust.php?mode=new&p=$i");
    my $res = $scraper->scrape($mech->content);
    for my $li (@{$res->{lists}->{li}}) {
        local $_ = $temp;
        s/%%LINK%%/$li->{link}/;
        s/%%SRC%%/$li->{image}/;
        s/%%COM%%/$li->{comment}/;
        print $enc_utf8->encode("$_\n");
    }
}
print qq(<body>\n</html>\n);

exit 0;

なんかCGI.pm使うのかったるかったので、html部分は手書きにしたけど、最近は別のモジュール使う方がいいのかしらん?

ついでなかんじがあるけど、Web::Scraper 初めて使ってみました。Xpathとか分からんので苦労したな〜。あ、あとリファレンスを多少でも理解してないと難しいのが分かったぞ

参照

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20100410

2009-05-31

[][WWW::Mechanize][Webスクレイピング]WWW::Mechanizeを使ってpixivへログインして、ごにょごにょする 21:39 [WWW::Mechanize][Webスクレイピング]WWW::Mechanizeを使ってpixivへログインして、ごにょごにょする - ishiducaの日記 を含むブックマーク はてなブックマーク - [WWW::Mechanize][Webスクレイピング]WWW::Mechanizeを使ってpixivへログインして、ごにょごにょする - ishiducaの日記 [WWW::Mechanize][Webスクレイピング]WWW::Mechanizeを使ってpixivへログインして、ごにょごにょする - ishiducaの日記 のブックマークコメント

WWW::Mechanize を使ってpixiv(SNS)にログイン-> 「お気に入りユーザー新着イラスト」のページ(1~10頁)のデータを抜き出してリストにする

#!/usr/bin/perl
use strict;
use warnings;
use encoding 'euc-jp', STDOUT => 'utf-8';
use WWW::Mechanize;

my $mech = new WWW::Mechanize(autocheck => 1);

my $uri  = 'http://www.pixiv.net/';
$mech->get($uri);

$mech->submit_form(
    fields => {
        pixiv_id => 'userID',
        pass     => 'password',
    },
);
$mech->get('http://www.pixiv.net/mypage.php');

(my $reg =<<'REG') =~ tr/\n//d;
<a href="(member_illust\.php\?mode=medium&illust_id=[0-9]{7})">
<img src="([^"]+)" border="0" /></a><br />
<div class="pdgTop5">([^<]+)</div>
REG
;

if( $ENV{GATEWAY_INTERFACE} ){
    require CGI;
    print CGI::header('text/plain; charset=utf-8');
}
foreach my $c (1..10){
    $mech->get("http://www.pixiv.net/bookmark_new_illust.php?mode=new&p=$c");
    my $html = $mech->content;
    while( $html =~ /$reg/gis ){
        my $page = "${uri}$1";
        print join("\t", $3, $2, $page), "\n";
    }
}

exit 0;

本当なら Web::Scraper を使えばいいんだろうけど、勉強中なので。

参照

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090531

2009-05-11

[][][][]Re: package宣言をして名前空間を定義する 20:24 Re: package宣言をして名前空間を定義する  - ishiducaの日記 を含むブックマーク はてなブックマーク - Re: package宣言をして名前空間を定義する  - ishiducaの日記 Re: package宣言をして名前空間を定義する  - ishiducaの日記 のブックマークコメント

端折りすぎました。

package宣言をして名前空間を定義する(はじめてのモジュール その2)では、以下のコードの中で「our」を使っていたんですが、モジュールファイル内で作ったグローバル変数をスクリプト内で使うためのインポート/エクスポートの処理が書いてありませんでした。このままでは、eto.pl ではグローバル変数のエラーが返ってしまいます。kits さんがはてブで「ourによる変数名のパッケージ名省略が可能なのは、あくまで宣言したブロック(ファイル)の範囲内のみ」とご指摘くださいました。

ex: ishiduca.pm(モジュールファイル)このままだと、$Year は eto.pl では使えない

package ishiduca; # モジュールファイル名でpackage宣言する
use strict;
our( $Year ); # 明示的には$ishiduca::Year
$Year = 1919;
# 以下省略
1;

ex: eto.pl(モジュールを使用するスクリプト)

#!/usr/bin/perl -wl
use strict;
use ishiduca;

print $Year; # ishiduca.pm でour(グローバル変数)宣言されているので、
             # エラーは出ない
             # 明示的にはprint $ishiduca::Year;

端折った部分を加えるとこう

ishiduca.pm

package ishiduca;
use strict;
our( $Year );
$Year = 1919;

# 以下、端折った部分
our(@ISA, @EXPORT);

require Exporter;
@ISA = qw( Exporter );

@EXPORT = qw( $Year );

1;

もしくは、eto.pl で、明示的に $ishiduca::Year とする

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090511

2009-05-06

[][][]package宣言をして名前空間を定義する(はじめてのモジュール その2) 14:26 package宣言をして名前空間を定義する(はじめてのモジュール その2) - ishiducaの日記 を含むブックマーク はてなブックマーク - package宣言をして名前空間を定義する(はじめてのモジュール その2) - ishiducaの日記 package宣言をして名前空間を定義する(はじめてのモジュール その2) - ishiducaの日記 のブックマークコメント

注:この記事には、間違っているところがあります。それは僕の理解不足によるところですが、ありがたいことに kits さんが、はてブでご指摘くださいました。ここでは、どこが間違っているのかは、明らかにしません。この記事の最後に間違えを訂正した記事へのリンクを張っておきますので、この記事を読み終えた後に続けて読んでいただけると幸いです。また、この記事へのツッコミも歓迎します。(2009.05.10 追記)


僕が購読している『ミニマルPerl』では詳しい説明が省略されているので、web上の文献を横断的に読んで箇条書きにしてみようと思ったけど、なかなか覚えきれないので、モジュール作成に関連したところだけを箇条書きにしてみる。

  • モジュール(ファイル)を作る時に、最初に宣言する。
  • package Module_name は Module_name の名前空間を定義する。
  • モジュール定義を保持するファイルでは、Module_nameはファイル名に対応する名前とパスを使用する。例えばMoudule_name を ishiduca と定義した場合は、ishiduca.pmだし、ishiduca::nengo とした場合は、ishiducaというディレクトリ下の nengo.pm。
  • 宣言した後に使われる(名前空間内で定義された)変数、サブルーチンは明示的にはModule_name::変数名、Module_name::サブルーチン名となる。
  • 宣言しない場合は暗黙的に package main される。
  • package名前空間の有効範囲は、package宣言をした位置から別のpackage文が現れるまで(ブロック内で宣言した場合は、そのブロック内)
  • package名前空間内でのみ使用する変数はmy宣言。他の名前空間でも使用する場合はour宣言する。

ex: ishiduca.pm(モジュールファイル)

package ishiduca; # モジュールファイル名でpackage宣言する
use strict;
our( $Year ); # 明示的には$ishiduca::Year
$Year = 1919;
# 以下省略
1;

ex: eto.pl(モジュールを使用するスクリプト)

#!/usr/bin/perl -wl
use strict;
use ishiduca;

print $Year; # ishiduca.pm でour(グローバル変数)宣言されているので、
             # エラーは出ない
             # 明示的にはprint $ishiduca::Year;

出力

1919

色々端折ってるからこんなに単純じゃないけど、イメージとして。


この記事には続き(Re: package宣言をして名前空間を定義する)があります。続けて読んでいただけると幸いです。



参照にした

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090506

2009-05-04

[]テンプレートを使ってモジュールを作成する(はじめてのモジュール) 19:33 テンプレートを使ってモジュールを作成する(はじめてのモジュール) - ishiducaの日記 を含むブックマーク はてなブックマーク - テンプレートを使ってモジュールを作成する(はじめてのモジュール) - ishiducaの日記 テンプレートを使ってモジュールを作成する(はじめてのモジュール) - ishiducaの日記 のブックマークコメント

『ミニマルPerl』で紹介しているモジュールのテンプレート(一般的な書式くらいの意)から新しいモジュールを作成して、ターミナルからモジュールを使えるようにする(スクリプトから使えるようにもする)。今日はその手順(端折って書く)。

  1. モジュールを置くディレクトリを作る
  2. テンプレートを編集してモジュールを作成、保存する
  3. モジュールをテストする(構文エラーチェック)
  4. モジュールの置き場所を指定する
  5. モジュールをテストする(スクリプトで使用する)
  6. モジュールの置き場所を設定ファイルに記述する

1. モジュールを置くディレクトリを作る

(適当に)ホームディレクトリに「myperl」ディレクトリをつくってみた

$ mkdir myperl

2. テンプレートを編集してモジュールを作成、保存する

テンプレートは以下の物を参照(それぞれ詳しい内容は別記事で書く...予定)

package Module_name;
use strict;
use Carp;

our(@ISA, @EXPORT, @EXPORT_OK);
our( module_vars, module_subs );

require Exporter; @ISA = qw/ Exporter /;

@EXPORT    = qw/ module_vars module_subs /;
@EXPORT_OK = qw/ module_vars module_subs /;

sub sub_ex{
    # some code;
}

1;

これが例えば干支を獲得する関数(get_eoto)を定義するモジュールだった場合

package ishiduca;
use strict;
use Carp;

our(@ISA, @EXPORT, @EXPORT_OK);

require Exporter;
@ISA = qw/ Exporter /;

@EXPORT    = qw/ get_eto /;
@EXPORT_OK = qw//;

# 西暦(YYYY)を引数にして、干支を返す
sub get_eto{
    my $usage = ":Usage:get_eto \"YYYY\"";
    @_ == 0 and
      # warn __PACKAGE__, $usage
      carp   __PACKAGE__, $usage
        and exit 255;
    local $_ = shift;
    my @eto = qw/申 酉 戌 亥 子 丑 寅 卯 辰 巳 午 未/;
    return $eto[ $_ % 12 ];
}

1;

(適当に)ishiduca.pmでmyperlディレクトリで保存

3. モジュールのテスト

まず、文法のテスト(オプションのcは構文エラーのチェック)

$ perl -wc ishiduca.pm

問題はなければ

ishiduca.pm syntax OK

と出る

4. モジュールの置き場所を指定する

この状態で使おうとしても次のような警告がでる

Can't locate ishiduca.pm ... compilation aborted

ので、Perlの検索リストを保管する環境変数PERL5LIBにモジュールが置かれたディレクトリのパスを追加する。それにはターミナルで

$ export PERL5LIB=$PERL5LIB:$HOME/myperl

と打つ。これで現在のシェルセッションで有効になる

5.モジュールをテストする(スクリプトで使用する)

テスト用のスクリプト(test.pl)

#!/usr/bin/perl -wl
use strict;
use ishiduca qw/ get_eto /;

# 引数を YYYY 形式のものだけに選別する
@ARGV = grep{ /^\d{4}$/ }@ARGV;
# 引数がない場合は、エラー処理
@ARGV == 0 and die "Usage: $0 YYYY [YYYY...]\n";

$, = "\n";
print map{ get_eto $_ }@ARGV;

exit 0;

実際に試してみる

$ perl test.pl 2007 2009 1971 1919

実行結果

亥
丑
亥
未

ワンライナーでもテスト

$ perl -Mishiduca -wle 'print get_eto $ARGV[0];' 2010
寅

6. モジュールの置き場所を設定ファイルに記述する

期待した結果が得られました。ただこの状態だと現在のシェルセッションでしかモジュールの位置をシェルに伝えられません。シェルにログインする度に export PERL5LIB=$PERL5LIB:$HOME/myperl と打つ代わりに、シェルのスタートアップファイル(~/.bash_login Kornシェルの場合は~/.profile)に、export PERL5LIB=$PERL5LIB:$HOME/myperl を追加します。このファイルが見当たらない場合は、新たに作成します。

これで、新たなセッションでログインしてもモジュールが使えるようになりました。



今回はモジュールの作成から使用可能にする設定までを重点にまとめ(?)てみました。

僕が購読している『ミニマルPerl』はモジュールの取扱はあまり重点的ではないのでそろそろ別の文献も必要かな

JamisonTaLJamisonTaL2018/02/09 16:52Shops that require protection for high risk goods held on the premises will usually need to declare the total values of each stock item. High risk shop stock and goods are those that attract thieves and are expensive to replace. Examples of high risk stock items are electronic equipment, cigarettes, and tobacco, designer clothing, computers and digital equipment, software, computer games and consoles, drugs pharmacy and medicines, watches and jewellery, mobile phones and radios, photographic equipment, power tools, TVs, DVDs, CDs and Wines and Spirits.

If your shop has high risk stock you can reduce the cost of your premiums by having adequate security in place. This includes an insurance company approved burglar and fire alarm, window grills, shutters and bars, CCTV and sprinklers. Many shop insurers will only offer stock cover if the minimum levels of security are in place for all shops, regardless of the stock contents held. A lot of insurers may offer further large discounts to the premium if the shop owner lives on or above the premises and is there at night.

Shops by their very nature deal with members of the public and a good insurance policy will usually contain liability cover as standard. This should include Public Liability of up to ?2,000,000 for any one claim by a member of the public who may suffer loss or injury visiting the shop.

If you employ staff all policies will offer Employers Liability cover of up to ?10,000,000 one event and because shops sell goods and services, Products Liability cover of ?2,000,000 for any one period of insurance.

<a href=https://www.cialissansordonnancefr24.com/etude-sur-le-cialis/>https://www.cialissansordonnancefr24.com/etude-sur-le-cialis/</a>

YolIndedaYolIndeda2018/02/15 05:25Dove Si Trova Viagra Zithromax To Buy Uk Baclofene Angers <a href=http://cialicost.com>cialis</a> Cialis 20mg Testberichte Cialis 10 Efectos Secundarios Viagra Sold In Usa

DomtaupDomtaup2018/04/16 20:34Atlantic Drug Store Viagra Canada Pharmacy Tadacip 10mg Paypal Colchicina En Canada <a href=http://cialiviag.com>cialis 40 mg</a> Does Cephalexin Contain Sulfa Clomid Acheter En Ligne Buying Cheap Propecia

AlbertthumeAlbertthume2018/06/01 20:03The prostate related is a vital a part of a male's reproductive :. It secretes fluids that aid in the transportation and activation of sperm. The prostate related can be found just before the rectum, below the bladder and around the urethra. When there is prostate problem, it is almost always really miserable and inconvenient for your patient as his urinary system is directly affected.

The common prostate health conditions are prostate infection, enlarged prostate and cancer of prostate.



Prostate infection, also called prostatitis, is the most common prostate-related symptom in men younger than 55 years of age. Infections of the men's prostate are classified into four types - acute bacterial prostatitis, chronic bacterial prostatitis, chronic abacterial prostatitis and prosttodynia.

Acute bacterial prostatitis could be the least common coming from all kinds of prostate infection. It is caused by bacteria perfectly located at the large intestines or urinary tract. Patients may go through fever, chills, body aches, back pains and urination problems. This condition is treated by using antibiotics or non-steroid anti-inflammatory drugs (NSAIDs) to help remedy the swelling.

Chronic bacterial prostatitis can be a condition associated with a particular defect within the gland and also the persistence presence of bacteria in the urinary tract. It can be a result of trauma to the urinary tract or by infections via other areas from the body. A patient can experience testicular pain, lower back pains and urination problems. Although it is uncommon, it may be treated by removal of the prostate defect as well as making use antibiotics and NSAIDs to help remedy the redness.

Non-bacterial prostatitis is the reason approximately 90% of all prostatitis cases; however, researchers have not yet to determine the cause of these conditions. Some researchers feel that chronic non-bacterial prostatitis occur due to unknown infectious agents while other believe intensive exercise and lifting might cause these infections.

Maintaining a Healthy Prostate

To prevent prostate diseases, an effective meals are important. These are some from the actions to keep your prostate healthy.

1. Drink sufficient water. Proper hydration is important for overall health and it will also keep the urinary track clean.

2. Some studies suggest that a few ejaculations each week will assist you to prevent prostate cancer.

3. Eat red meat sparingly. It has been shown that consuming greater than four meals of beef a week will heighten the chance of prostate diseases and cancer.

4. Maintain a suitable diet with cereals, vegetable and fruits to make sure sufficient intake of nutrients necessary for prostate health.

The most critical measure to look at to make sure a healthy prostate is usually to opt for regular prostate health screening. If you are forty years of age and above, you need to opt for prostate examination at least once 12 months.

ACruitCawfafACruitCawfaf2018/07/25 12:13Pression arterielle est comment poupe votre sang pousse contre les parois de vos arteres lorsque votre coeur determination pompe le sang. Arteres sont les tubes qui transportent prendre offre sang loin de votre coeur. Chaque temps votre manque de sensibilite bat, il pompe le sang a tous egards vos arteres a la prendre facilement de votre corps.
https://www.cialispascherfr24.com/le-prix-du-cialis-au-maroc/

AAliernLingeAAliernLinge2018/09/23 22:54 Poids est comment dur votre sang pousse contre les parois de vos arteres lorsque votre coeur determination pompe le sang. Arteres sont les tubes qui transportent perseverent b gerer offre sang loin de votre coeur. Chaque age votre moelle bat, il pompe le sang par de vos arteres a la prendre facilement de votre corps.
https://www.cialispascherfr24.com/cialis-puerto-rico/

トラックバック - http://perl.g.hatena.ne.jp/ishiduca/20090504