Perl way to explore https:https://cdn.v2ex.com/navatar/202c/b962/123_normal.png?m=1439985149 https:https://cdn.v2ex.com/navatar/202c/b962/123_large.png?m=1439985149 2022-11-11T04:54:38Z Copyright © 2010-2018, V2EX 一段 perl 代码展示如何 all in one 优雅地编写一个异步爬虫 tag:www.v2ex.com,2022-09-15:/t/880334 2022-09-15T10:28:30Z 2022-11-11T04:54:38Z dfgddgf member/dfgddgf #cpan https://cpan.metacpan.org/authors/id/S/SR/SRI/Mojolicious-7.31.tar.gz #cpanm -n Mojolicious@7.31 use feature ':5.10'; use strict; use warnings; use utf8; use Mojo; use Encode qw(decode encode); ########################################################################## $ENV{MOJO_REACTOR} = 'Mojo::Reactor::EV'; #使用 EV 具有更好的性能 my $ua = Mojo::UserAgent->new; $ua->inactivity_timeout(60); $ua->connect_timeout(60); $ua->request_timeout(60); #适当延长超时的时间,阻止过早的 http 请求失败,会有更好的性能 $ua->max_connections(1000); #最大连接数 1000 $ua->max_redirects(0); #阻止 http3xx 重定向 $ua->transactor->name('Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0'); #使用正常浏览器的 user agent $ua->cookie_jar->ignore( sub { 1 } ); #禁用 Mojo::UserAgent 自动处理 cookie $ua->proxy->http('http://127.0.0.1:8080')->https('http://127.0.0.1:8080'); #使用代理服务器 ########################################################################## my @list = (); #原始队列 my @urllist = (); #下载队列 my $n = 0; #下载数量 my $m = 0; #出错数量 my $produce_num = 0; #生产者数量 my $consumer_num = 0; #消费者数量 my $cookie_num = 0; #cookie 数量 my @cookielist = (); #使用的 cookie 队列 my %cookieinvalid = (); #失效的 cookie 散列 ########################################################################## open FILEIN, '<', "./url.txt" or die "$!"; while (<FILEIN>) { my $cOntent= $_; chomp($content); $cOntent=~ s/\r//; push( @list, $content ); } close FILEIN; #导入下载列表 ########################################################################## sub append_txt_to_file { my $file_name = $_[0]; my $txt = $_[1]; local *FH; open FH, '>>', $file_name; print FH $txt; close FH; } sub write_txt_to_file { my $file_name = $_[0]; my $txt = $_[1]; local *FH; open FH, '>', $file_name; print FH $txt; close FH; } my %safe_character = ( '<' => '<', '>' => '>', ':' => ':', '"' => '"', '/' => '/', '\\' => '\', '|' => '|', '?' => '?', '*' => '*', ); sub repace_safe { my $per_char = $_[0]; my $one_txt = $_[1]; my $output_char; if ( exists $safe_character{$per_char} ) { $output_char = $safe_character{$per_char}; } else { $output_char = $per_char; } return $output_char; } sub find { my $html_bin = $_[0]; my $id = $_[1]; if ( $html_bin =~ m/<\/html>/ ) { return '####'; } else { return '@@@'; } } ########################################################################## sub get_multiplex { my $id = $_[0]; my $delay = Mojo::IOLoop->delay( sub { get_multiplex($id) } ); #get_multiplex 递归迭代的开始标记 #$id 是每一个线程(端口的序号) my $end = $delay->begin; Mojo::IOLoop->timer( 0.1 => $delay->begin ); #每个 http 请求前暂停 0.1s if ( scalar @urllist == 0 ) { if ( $produce_num == $consumer_num ) { Mojo::IOLoop->stop; #异步循环结束 #当队列数量为 0 ,且所有的线程数据都处理完毕的时候,终止事件循环 #return 存在一个递归返回链,这里可以更快地结束 } return; #这里返回后异步任务数量为 0 时,系统会自动结束异步循环,不过速度较慢 #return 返回闭包函数的开始,并结束闭包函数,下面不开启递归自身 } else { my $object = shift @urllist; $produce_num++; my $url = $object; my $filename = $object; $filename =~ s/^http:\/\/www\.bing\.com\/w\///m; $filename =~ s/(.)/repace_safe($1)/eg; $filename = "./www.bing.com/" . $filename . ".html"; if ( -e $filename ) { syswrite STDERR, encode( 'utf8', $n . "\t" . $object . "\t 跳过\n" ); #STDOUT 编码已改,输送到 STDOUT 会出现错误 $consumer_num++; $end->(); } else { my $build_tx = $ua->build_tx( GET => $url ); $build_tx->req->headers->remove('Accept-Encoding'); #阻止网页压缩,保证更好的性能 $build_tx->req->headers->add( 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' ); $build_tx->req->headers->add( 'Accept-Language' => 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' ); $ua->transactor->name( 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:' . int( rand(900) ) . ') Gecko/' . int( rand(40000001) ) . ' Firefox/' . int( rand(900) ) . '.0' ); #使用 2 万个 cookie $ua->start( $build_tx => sub { my ( $ua, $tx ) = @_; if ( !$tx->is_finished ) { push( @urllist, $object ); syswrite STDERR, "http 传输未完成" . "\n"; syswrite STDERR, encode( 'utf8', $url . "\t" . $tx->error->{message} . "\n" ); } else { my $code = ''; $code = $tx->res->code if defined $tx->res->code; if ( $code =~ /\A2/ ) { my $size = $tx->res->content->asset->size; my $content_length = $tx->res->headers->to_hash->{'Content-Length'}; if ( ( $size == $content_length ) || !( defined $content_length ) ) { my $outnum = find( $tx->res->body, $id ); if ( $outnum ne '@@@' ) { append_txt_to_file( "url.txt", $object . "\t" . $outnum . "\n" ); write_txt_to_file( $filename, $tx->res->body ); $n++; syswrite STDERR, encode( 'utf8', $n . "\t" . $object . "\n" ); } else { $n++; syswrite STDERR, encode( 'utf8', $m . "\t" . $object . "\t 网页下载完整但未提取到数据\n" ); } } else { $m++; push( @urllist, $object ); syswrite STDERR, encode( 'utf8', $m . "\t" . $object . "\t 网页未下载完整\n" ); } } elsif ( $code =~ /\A4/ ) { syswrite STDERR, encode( 'utf8', $m . "\t" . $object . "\thttp 4xx\n" ); push( @urllist, $object ); Mojo::IOLoop->timer( 0.5 => $delay->begin ); #http 404 } else { $m++; push( @urllist, $object ); syswrite STDERR, encode( 'utf8', $m . "\t" . $object . "\t 未发现 http code, http 3xx, http 5xx\n" ); #标记失效的从 cookie http 3xx Mojo::IOLoop->timer( 0.5 => $delay->begin ); #服务器返回 5xx ,暂停 0.5s #未发现 http code, http 302, http 503 } } $consumer_num++; $end->(); #get_multiplex 递归迭代的结束标记 #从这里跳转到下一个 get_multiplex } ); } } } ########################################################################## $produce_num = 0; $consumer_num = 0; @urllist = @list; #异步下载前的变量准备 foreach my $id ( 1 .. 50 ) { get_multiplex($id) } #使用 50 个线程(端口)下载 #如果线程数是 100 ,限制最大 cookie 数无法生效,并且 EV 会出现错误 Mojo::IOLoop->start; #异步循环启动 ########################################################################## ]]> Perl 怀旧群 tag:www.v2ex.com,2022-01-09:/t/827149 2022-01-09T09:48:10Z 2022-06-17T00:37:53Z alexecn member/alexecn

还有喜欢 Perl 的朋友,可以加群。

小众群

长期进群,加微信:wwmm9ww

]]>
安装社区版 perl 时的注册问题 tag:www.v2ex.com,2021-11-06:/t/813465 2021-11-06T04:14:26Z 2021-11-06T00:13:26Z xiaoming1992 member/xiaoming1992 安装 vscode latex 插件时需要 perl, 所以从 perl 官网找到了 windows 社区版,
https://www.activestate.com/products/perl/, 下载需要注册,点击 github 注册时, 提示需要访问我的私有库的只读权限, 我不知道是不是我理解有误?还是说他确实需要我授权访问我的私有库?如果是,我不太明白为什么要访问我的私有库...

申请授权截图

]]> 有没有业余学 perl 作为爱好的 tag:www.v2ex.com,2020-02-14:/t/644665 2020-02-14T14:48:20Z 2020-08-15T02:17:38Z zjq123 member/zjq123 perl 还值得学吗 tag:www.v2ex.com,2018-10-14:/t/497535 2018-10-14T09:25:26Z 2018-11-25T07:26:50Z jiafaner member/jiafaner
现在是两个方案,一个是老板的方案,另一个是用 PHP 重写,老板说重写的风险高于扩展,建议学点 perl

网上都找不到 perl 的资料了,这个语言还值得学吗,现在还有人用吗,还有什么优势没 ]]>
来一起学习 Perl 6 阿 tag:www.v2ex.com,2017-05-15:/t/361473 2017-05-15T09:01:29Z 2017-11-12T20:25:20Z araraloren member/araraloren Perl 6 的实现 rakudo 已经开发的很好了,有人有兴趣一起来学习 Perl 6 么?

Perl 6 主页

rakudo 主页

顺便附上我做的模块地址,欢迎各位 star

https://github.com/araraloren/perl6-terminal-table

下面的东西摘自 wiki

Perl 6 是编程语言 Perl 语言的后续。由于 Perl 6 语言语法与 Perl 5 不同,因此,可以把它看作一种 新的编程语言,尽管其计划提供 Perl 5 的兼容模式。 Perl 6 拥有丰富的现代语言特征,拉里·沃尔计划用重新定义正规表达式和增加函数式编程语言的特 征,使之成为可演化的语言。为保证 Perl 6 和 Perl 社区的持续稳定发展,Perl 6 编译器需要使用 Perl 6 来重写。为保证 Perl 语言原有库的重用,编译器还计划提供同 Perl 5 语言的兼容模式。 由于 Perl 6 语言的语法特征和要求,Perl 6 编译器实现非常复杂,同时,自由软件社区的资源相对 贫乏。因此,Perl 6 编译器的开发显得相当缓慢。 

BTW: Perl 真的好冷清,这个节点一年也就一个帖子

BTW2: 还是喜欢 asciidoc

]]>
Perl 学习地 tag:www.v2ex.com,2016-03-02:/t/260530 2016-03-02T07:44:56Z 2016-03-02T12:33:08Z chenhui7373 member/chenhui7373 http://perl.linuxtoy.org/contents.html

https://github.com/briandfoy/Learning-Perl-Sample-Files

http://perltricks.com/

http://qntm.org/files/perl/perl_cn.html

deerchao.net/tutorials/regex/regex.htm

http://www.chengxuyuans.com/manual/perl/ ]]>
新手学 perl,想问一下 print 数字的时候,为什么后面总是跟着一个“%” tag:www.v2ex.com,2015-05-08:/t/189425 2015-05-08T03:35:52Z 2015-05-13T04:17:32Z sinux member/sinux perl 的打包部署问题 tag:www.v2ex.com,2014-07-16:/t/122863 2014-07-16T02:25:14Z 2014-07-16T09:21:57Z tychio member/tychio
初步推断应该是打包过的,但是没找到打包后的代码和文件,也没找到相关的脚本或配置文件用于打包。目录里只有一个build.yml,不过貌似是安装第三方包用的。

有人遇到过这种状况吗 ]]>
Perl 爬取内容失败 tag:www.v2ex.com,2014-06-30:/t/120329 2014-06-30T16:07:54Z 2014-06-30T23:29:37Z akagi member/akagi
"Can't call method "all_text" on an undefined value at core.pl line 188."

实现如下,

sub get_keyword_list {
my ($ua, @list, $keyword) = @_;

foreach my $l (@list) {
my $tx = $ua->get($l->[0]);
say $l->[0];
# what should it be?
my $answer = $tx->res->dom->at('div.zm-editable-content.clearfix')->all_text;
my $timestamp = $tx->res->dom->at('a.answer-date-link.meta-item')->text;
open my ($tmp), '>>', 'tmp.txt' or die;
say $tmp $answer;
say $tmp $timestamp;
}
}

其中 $l->[0] 取到列表中各网页 url, 类似如下形式: http://www.zhihu.com/question/20304733/answer/25775012

为什么会出现错误,无法理解ing, 求解。 ]]>
连永远的毁灭公爵都发布了 perl6还没有完工 tag:www.v2ex.com,2011-07-05:/t/15364 2011-07-05T08:37:17Z 2012-07-10T07:31:46Z dongsheng member/dongsheng
一年前我工作的一个项目也用同样的答案回答开源社区,但这种答案其实是傲慢且不负责任的。一个把开发周期拖得如此长的项目对这个语言本身和开源社区的伤害都是很大的。 ]]>
perl6就要出来了,大家有期待的吗? tag:www.v2ex.com,2010-07-29:/t/1098 2010-07-29T09:56:57Z 2013-07-11T08:07:08Z itopidea member/itopidea ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86