Perl 提取 AliExpress 订单详情

There's more than one way to do it!
https://metacpan.org http://perlmonks.org
回复
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Perl 提取 AliExpress 订单详情

帖子 523066680 »

占位、索引
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Step 1 - 获取详情页

帖子 523066680 »

Login 模块用于登录,返回登录过的 Mojo::UserAgent 对象,另外开帖讨论这个。

代码: 全选

=info
    获取 AliExpress 订单详情页面
    2019-08-28
=cut

use utf8;
use Encode;
use Modern::Perl;
use File::Slurp;
use Time::HiRes 'sleep';
use Date::Format;
use Mojo::UserAgent;
use Mojo::DOM;
use FindBin;
use Storable qw/retrieve/;
use lib "$FindBin::Bin/../../lib";
use Login;
STDOUT->autoflush(1);

my $ua = Mojo::UserAgent->new();

Login::init( $ua );

my $id = "8000...这里填入新版本的订单号";
get_detail($ua, $id);

sub get_detail
{
    my ($ua, $id ) = @_;
    my $link = "https://gsp-gw.aliexpress.com/openapi/param2/1/gateway.seller/api.order.detail.get";
    my $retry = 0;
    my $res;
    my %args = (
        "_timezone" => -8,
        "orderId" => $id,
    );

    while ( $retry <= 5 )
    {
        $res = $ua->get( $link, form => \%args )->result;
        last if $res->is_success();
        sleep 1.0;
        say ++$retry;
    }
    say "get detail false" if ( !$res->is_success() );

    print $res->body;
    write_file( sprintf("src_%s.json", substr($id, -4) ), $res->body );
}

sub gbk { encode('gbk', $_[0]) }
sub u2gbk { encode('gbk', decode('utf8', $_[0])) }
返回 json 数据
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

Step 2 - 从 JSON 中提取订单信息、客户资料

帖子 523066680 »

从 JSON 中提取订单信息、客户资料

代码: 全选

=info
    提取 AliExpress 订单详情
    Author: 523066680/vicyang
      Date: 2019-08-28
=cut

use utf8;
use Encode;
use File::Slurp;
use Date::Format;
use Data::Dump qw/dd/;
use JSON qw/from_json/;
STDOUT->autoflush(1);

my $json = read_file("pretty_2565.json");
#my $json = read_file("pretty_3520.json");
my $data = from_json($json);
my $info = {};
abstract( $data, $info );

sub abstract
{
    my ($data, $info) = (@_);
    my $node = $data->{data}{modules};
    my $ele = match( $node, "name", "Order Detail", "elements");
    #dd $ele;
    my $ordernum = $ele->[1]{elements}[0]{elements}[1]{elements}[0]{content};
    my $nickname = $ele->[2]{elements}[0]{elements}[1]{elements}[0]{content};
    my $contact = $ele->[2]{elements}[1]{elements}[1]{content};
    my $address = $ele->[2]{elements}[1]{elements}[2]{content};
    
    my $color = $ele->[3]{modules}[0]{dataSource}[0]{product}{elements}[1]{content};
    my $shipsfrom = $ele->[3]{modules}[0]{dataSource}[0]{product}{elements}[2]{content};
    my $model = $ele->[3]{modules}[0]{dataSource}[0]{product}{elements}[3]{content};
    my $seller = $ele->[3]{modules}[0]{dataSource}[0]{product}{elements}[4]{content};

    my $title = $ele->[3]{modules}[0]{dataSource}[0]{product}{title};
    my $url = $ele->[3]{modules}[0]{dataSource}[0]{product}{url};
    my $productID = $url =~ /(\d+)$/ ? $1 : "";
    my $price = $ele->[3]{modules}[0]{dataSource}[0]{price};
    my $total = $ele->[3]{modules}[0]{dataSource}[0]{total};
    my $count = $ele->[3]{modules}[0]{dataSource}[0]{count};

    $ele = match( $node, "name", "Fund Detail", "elements");
    my $freight = $ele->[2]{modules}[0]{dataSource}[0]{shippingFee}[0]{content};
    my $commission = $ele->[2]{modules}[0]{dataSource}[0]{commission};
    my $promotion = $ele->[2]{modules}[0]{dataSource}[0]{storePromotion};
    my $adjust = $ele->[2]{modules}[0]{dataSource}[0]{adjustPrice}[0]{content};
    my $orderPrice = $ele->[2]{modules}[0]{dataSource}[0]{orderPrice}[0]{content};
    my $productPrice = $ele->[2]{modules}[0]{dataSource}[0]{productPrice}[0]{content};
    my $paytime = $ele->[4]{modules}[0]{dataSource}[0]{payDate};

    $ele = match( $node, "name", "orderBasicInfo", "elements");
    my $status = $ele->[2]{content};

    printf "%s %s\n", $paytime, $status;
    printf "%s %s\n", $productID, $title;
    printf "%s %s\n", $ordernum, $nickname;
    printf "%s %s\n", $contact, $address;
    printf "%s %s %s %s\n", $model, $color, $shipsfrom, $seller;
    printf "%s %s %s\n", $price, $count, $total;

    printf "%s %s %s %s %s\n", $productPrice, $freight, $promotion, $adjust, $orderPrice;

}

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";
}


=struct
data
  modules [
    {订单状态 name => orderBasicInfo}, # 剩余发货时间、订单状态
    # 如果已经发货,则此栏目为物流信息
    {订单详情 name => Order Detail},
    {资金详情 name => Fund Detail},

订单详情
  elements [
    0 Order Overview,
    1 elements [ 
            { elements [ 标题, {订单号} ] },
            { elements [标题, {订单备注} ] },
        ],
    2 elements [
            { 大标题 }
            { 标题, {用户名}, {联系买家,查看留言,举报 等} },
            { 收件地址, {联系人+电话}, {地址+邮编}, {复制} }
        ],
    3 modules [
        0 - dataSource
            0 product
                elements [ 0, color, ships from, model, seller ]
                title title
                total total
                price price
                count count
        1 - dataSource (如果该订单有多款产品)
    ]

资金详情
  elements [
    {大标题 Fund Details},
    {子标题 Order Amount},
    {
        columns [列标],
        dataSource [
            "ShippingFee" => [ {USD}, {地区货币} ],
            "escrowCommission" => "交易佣金",
            "affiliateCommission" => "联盟佣金",
            "storePromotion" => "店铺优惠",
            "estimateRevenue" => "预计可得",
            "adjustPrice" => [ {} ... ],
            "orderPrice" => [ {USD}, {地区货币} ],
            "productPrice" => [ {USD}, {地区货币} ],
        ]
    }
=cut
头像
523066680
Administrator
Administrator
帖子: 573
注册时间: 2016年07月19日 12:14
联系:

客户信息 Parse

帖子 523066680 »

新版详情页的客户信息是合并的,但是我们发货的时候省份、城市、邮编、名称、电话需要分开填写
所以这里做一个提取
=info 客户信息 Parse Author: 523066680/vicyang Date: 2019-08-28 =cut use utf8; use Encode; use Modern::Perl; STDOUT->autoflush(1); my $contact = "User Name, +35-PhoneNumber"; my $address = "Rua de Santo Antonio, Lisboa, Odivelas, Portugal, 2675-440"; my ($name, $tel) = split(", ", $contact); my @parts = split(", ", $address); my ($city, $prov, $country, $zipcode) = splice @parts, -4; my $addr = join(", ", @parts); printf "Name: %s\n", $name; printf "Tel: %s\n", $tel; printf "Zip Code: %s\n", $zipcode; printf "Address: %s\n", $addr; printf "%s, %s, %s\n", $country, $prov, $city;
处理结果
Name: User Name
Tel: +35-PhoneNumber
Zip Code: 2675-440
Address: Rua de Santo Antonio
Portugal, Odivelas, Lisboa
回复

在线用户

正浏览此版面之用户: 没有注册用户 和 0 访客