标题: [原创代码] 某电商平台订单信息批量获取、格式化输出、分类统计 [打印本页]
作者: 523066680 时间: 2019-7-13 08:47 标题: 某电商平台订单信息批量获取、格式化输出、分类统计
现在搞跨境电商,- =info
- Get Orders from Ali Platform
- 523066680/vicyang
- 2019-07
- =cut
-
- use utf8;
- use Encode;
- use Modern::Perl;
- use File::Slurp;
- use File::Basename;
- use Mojo::UserAgent;
- use Time::HiRes qw/time sleep/;
- use Date::Format;
- use Date::Parse;
- STDOUT->autoflush(1);
-
- my $ua = Mojo::UserAgent->new();
- $ua = $ua->request_timeout(5);
-
- my $data = get_online_data($ua);
- my $list = [];
- data_abstract($data, $list);
-
- my $time_a;
- my $begin = time2str("%Y-%m-%d", time() - 24*60*60 ) ." 17:00";
- my $end = time2str("%Y-%m-%d", time()) ." 17:00";
-
- # dumping
- my %calcu;
- my $count;
- my $slen = 0;
- for my $e ( @$list )
- {
- next if ( $e->{'time'} gt $end or $e->{'time'} lt $begin );
- printf "%s %s %s %6s %s %s %s %s %s %s\n",
- $e->{'time'},
- substr($e->{'ordernum'}, -5),
- gbk("发货地:"),
- $e->{'from'},
- $e->{'model'},
- $e->{'color'},
- $e->{'count'},
- $e->{'unit'},
- $e->{'status'},
- $e->{'to'},
- ;
- # 统计
- $count = $e->{unit} eq gbk('台') ? $e->{count} : $e->{count}*2;
- $slen = length($e->{model}) if length($e->{model}) > $slen;
- if (exists $calcu{ $e->{model} }) {
- $calcu{$e->{model}} += $count;
- } else {
- $calcu{$e->{model}} = $count;
- }
- }
-
- say gbk("分类统计:");
- for my $model ( sort keys %calcu )
- {
- printf "%-${slen}s %d pcs\n", $model, $calcu{$model};
- }
-
- sub data_abstract
- {
- our ($COUNTRY, %country);
- my ($data, $list) = @_;
- say "Data processing ... ";
- my $node = match( $data->{data}{modules}, "name", "orderTable", "dataSource" );
-
- for my $e ( map { @{$_->{children}} } @$node )
- {
- #say $e->{'children'};
- my $ordernum = match( $e->{orderInfo}, "label", "订单号", "content" );
- my $time = match( $e->{orderInfo}, "label", "下单时间", "content" );
- my $buyer = (match( $e->{orderInfo}, "label", "买家", "options" ))->[0]{content};
- my $sku = match( $e->{productInfo}{elements}, "label", "商品属性", "content" );
- my $model = match( $e->{productInfo}{elements}, "label", "商品编码", "content" );
- my $status = $e->{orderStatus}[0]{content};
- my ($quantity) = $e->{productInfo}{elements}[1]{content} =~ /x (\d+)/;
- my $title = $e->{productInfo}{title};
- my $seller;
-
- next if $status =~ "等待买家付款";
- next if $status =~ "资金处理中";
- next if $status =~ "订单关闭";
- $status = " 已发货 " if $status =~ "等待买家收货";
- my $from;
- if ( $sku =~ /([\w\s]+) \+/ ) { $from = $1 } else { $from = "China" }
-
- my $color = $sku;
- my $unit = "台";
- if ($title=~/2 ?(pc|piece|unit)s?/i) {
- $unit = "对";
- }
-
- my $CNtime = time2str( "%Y-%m-%d %R", str2time($time) + 15*3600 );
- $CNtime=~s/T/ /;
- $CNtime=~s/:00$//;
-
- my $colorx = color_recognize( $color, $model );
- $model = model_number($model);
-
- #printf "%s %s %s %s %s\n", $orderID, $time, $model, gbk($colorx), $quantity;
- my ($zipcode, $target) = get_detail( $ua, $ordernum );
- $target = $COUNTRY->{$target}[0] if (exists $COUNTRY->{$target});
- push @$list, {
- 'time' => $CNtime,
- 'ordernum' => $ordernum,
- 'from' => gbk($country{$from}),
- 'model' => $model,
- 'color' => gbk($colorx),
- 'count' => $quantity,
- 'unit' => gbk($unit),
- 'status' => gbk($status),
- 'to' => gbk($target),
- }
- }
- }
-
- sub get_detail
- {
- my ($ua, $id ) = @_;
- my $link = "https://trade.aliexpress.com/order_detail.htm?orderId=" . $id;
-
- my $res = $ua->get( $link )->result;
- say "get detail false" unless $res->is_success();
- my $dom = $res->dom;
-
- my $zipcode;
- my $address;
- for my $e ($dom->find("span[i18entitle]")->each ) {
- if ($e->attr("i18entitle") =~ /Zip Code/i) { $zipcode = $e->text; }
- }
-
- $address = $dom->find(".long .i18ncopy")->map("text")->join("");
-
- # special: Croatia (local name: Hrvatska)
- $address =~s/\(.*\)//g;
- $address =~s/(\r|\n)//g;
- $address =~s/\s+$//g;
- ($address) = $address =~ /,\s+([^,]+)$/;
-
- return ($zipcode, $address);
- }
-
- sub match
- {
- my ( $arr, $key, $value, $item ) = @_;
- for my $e ( @$arr ) {
- return $e->{$item} if ( exists $e->{$key} and $e->{$key} =~ /$value/ );
- }
- return "NOT FOUND";
- }
-
- sub model_number
- {
- my ($model) = @_;
- my $actual = "";
-
- # 根据SKU选择项目或者标题,提取实际产品型号
-
- return $actual;
- }
-
- # 统一颜色标识
- sub color_recognize
- {
- my ($color, $model) = @_;
- my $colorx = "";
- my %cmap = ('black'=>"黑色", 'beige'=>"米色", 'gray'=>"灰色" );
-
- if ( $model =~/(Black|Gray|Grey|Beige)/i ) {
- $colorx .= $1;
- } else {
- if ( $color =~/(Black|Gray|Grey|Beige)/i ) {
- $colorx .= $1;
- } else {
- $colorx .= "Black";
- }
- }
- $colorx=~s/Grey/Gray/i;
- $colorx=~s/None/Black/i;
-
- return $cmap{lc $colorx};
- }
-
- sub get_online_data
- {
- my ($ua) = @_;
- my $res;
- my $dom;
-
- my %headers = (
- "User-Agent" => "Mozilla/5.0 Firefox/67.0",
- "Upgrade-Insecure-Requests"=> "1",
- "Connection" => "keep-alive",
- );
-
- my %args =(
- "loginId" => '账号',
- "password2" => "256位密钥,通过火狐调试模式获取",
- "isMobile" => "false",
- "mobile" => "false"
- );
-
- my $url = "https://passport.aliexpress.com/newlogin/login.do?appName=aebuyer&fromSite=13";
- $res = $ua->post( $url, \%headers, form => \%args )->result;
- say "false" unless $res->is_success();
- # {"content":{"data":{"miniVsts":[],"st":"1ZNq0FM2sJ6ssd_O7n98drw", ...
-
- my $st = $res->json->{'content'}{'data'}{'st'};
- say "st: ", $st;
-
- # step 2
- # validateSTGroup is necessary
- my $url2 = "https://login.aliexpress.com/validateSTGroup.htm";
- %args = (
- "st" => $st,
- "join_from" => "aliexpress",
- "pattern" => "common",
- "passport" => '账号',
- "scene" => "AE_MAIN_LOGIN",
- );
-
- $res = $ua->get( $url2, \%headers, form => \%args )->result;
-
- # https://mojolicious.org/perldoc/Mojo/UserAgent/CookieJar
- for my $e ( @{$ua->cookie_jar->all} ) {
- if ($e->name eq "aep_usuc_f") { $e->value( $e->value . "&s_locale=zh_CN" ); }
- }
-
- $url = "https://gsp-gw.aliexpress.com/openapi/param2/1/gateway.seller/api.order.list.get";
- %args = (
- "_timezone" => "-8",
- "lastSelectOrderStatus" => "all",
- "orderTab" => "Null",
- "refreshPage" => "false",
- "orderStatus" => "all",
- "filterCondition" => "OrderId",
- "current" => "1",
- "pageSize" => "50" # 一页的项数 10 20 50 100
- );
-
- $res = $ua->post( $url, form => \%args )->result;
- say "false" unless $res->is_success();
- return $res->json;
- }
-
- sub gbk { encode('gbk', $_[0]) }
-
- BEGIN
- {
- use Storable qw/retrieve/;
- # ref->{'English Name'} = [ zhCN_Name, CountryCode ]
- our $COUNTRY = retrieve("CountryName_EN2CN.perldb");
- our %country = ( 'China' => '中国', 'Spain' => '西班牙', 'Russian Federation' => '俄罗斯' );
- }
复制代码
国家名称映射表,英文转中文
$COUNTRY->{'English Name'} = [ 中文名, 英文名国际缩写 ]
输出结果(手动改了型号)- Data processing ...
- 2019-07-13 07:17 64820 发货地: 中国 R10001 黑色 1 台 等待您发货 巴西
- 2019-07-13 06:09 93991 发货地: 中国 R30001 黑色 2 台 等待您发货 法国
- 2019-07-13 05:39 36966 发货地: 中国 R30002 黑色 1 台 等待您发货 西班牙
- 2019-07-13 00:13 95071 发货地: 俄罗斯 R20001 黑色 1 台 等待您发货 俄罗斯
- 2019-07-12 23:39 65233 发货地: 俄罗斯 R30003 黑色 2 台 等待您发货 俄罗斯
- 2019-07-12 21:43 19126 发货地: 西班牙 R20001 灰色 1 对 已发货 西班牙
- 2019-07-12 17:55 35787 发货地: 西班牙 R30005 灰色 1 台 等待您发货 西班牙
- 分类统计:
- R30002 1 pcs
- R30001 2 pcs
- R10001 1 pcs
- R20001 3 pcs
- R30003 2 pcs
- R30005 1 pcs
复制代码
分类统计的时候会判断单位是台还是对,一对的项目数量*2
时间范围限定:- my $begin = time2str("%Y-%m-%d 17:00", time() - 24*60*60 );
- my $end = time2str("%Y-%m-%d 17:00", time());
复制代码
作者: 523066680 时间: 2019-7-13 08:51
时间原本是美国时间,通过 Data::Parse 和 Data::Format 模块,解析为时间戳+15小时,再格式化输出。- my $CNtime = time2str( "%Y-%m-%d %R", str2time($time) + 15*3600 );
复制代码
其实有时区转换的模块,但是一写发现还没这两个模块简洁
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |