2023年11月27日发(作者:)

让我们来⽤php编写⼀个抢购商品脚本

环境

php7.2

guzzle

thinkphp5.1

说明

0. git clone xxxxxx

1. composer create-project topthink/think=5.1.* fxbox

2. cd fxbox

3. composer require guzzlehttp/guzzle:~6.0 安装 guzzle

4. composer update

创建cli 指令

php think make:command Fcbox fxbox

⽂档地址:

效果图

核⼼代码

namespace appcommand;

use GuzzleHttpCookieCookieJar;

use thinkconsoleCommand;

use thinkconsoleInput;

use thinkconsoleOutput;

class Fcbox extends Command

{

private $userInfo = [];

private $cookies = '';

private $skus = '';

private $address = [];

//

数量

private $count = 0;

//

⽤户列表的下标

private $current_address = 0;

// sku

列表的下标

private $current_sku = 0;

//

抢购开始时间

private $start_time = 0;

//token

⽣成订单的

private $orderToken = 0;

public $client = null;

public $jar = null;

public $output = null;

public function __construct($name = null)

{

parent::__construct($name);

$this->client = new GuzzleHttpClient(); //

初始化客户端

$this->jar = new CookieJar();

$this->output = new Output();

//

获取⽤户信息

$this->cookies = $this->inputCookie();

//

订单结束

}

protected function configure()

{

//

指令配置

$this->setName('fcbox:run');

//

设置参数

}

protected function execute(Input $input, Output $output)

{

$this->output->writeln("-------------正在获取个⼈信息中-------------");

$this->userInfo = $this->getUserInfo(); //

⽤户信息

$this->address = $this->getUserAddress(); //

⽤户地址

$this->output->writeln("----------------------------------------------------------------------");

// sku

获取产品信息价格描述产品名称

$this->skus = $this->getProduct(); //

产品信息

$this->output->writeln("----------------------------------------------------------------------");

// sku

选择信息

$this->selectProductSku();

$this->output->writeln("----------------------------------------------------------------------");

//

选择数量

$this->getInputCount();

$this->output->writeln("----------------------------------------------------------------------");

//

选择地址

$this->selectUserAddress();

$this->output->writeln("----------------------------------------------------------------------");

//

抢购开始的时间

$this->getInputStartTime();

$this->output->writeln("----------------------------------------------------------------------");

/**

*

*

这⾥需要循环进⾏下单

*

*

*/

//

提交订单

while (true) {

sleep(5);

}

// token

⽣成提交订单的信息认证

$this->getConfirmToken();

$this->output->writeln("----------------------------------------------------------------------");

//

提交订单

$this->submitOrder();

$this->output->writeln("----------------------------------------------------------------------");

//

脚本执⾏结束

$this->output->writeln("----------------------------------------------------------------------");

$this->output->writeln("------------------------------脚本执⾏完成------------------------------");

$this->output->writeln("----------------------------------------------------------------------");

}

/**

* cookie

对⽤户输⼊的进⾏处理

* @return CookieJar

*/

private function inputCookie()

{

try {

fwrite(STDOUT, '请输⼊你的Cookies:');

$cookies = trim(fgets(STDIN));

$cookies = explode(';', $cookies);

$base_url = '';

$data = [];

foreach ($cookies as $cookie) {

if ($cookie == '') continue;

[$name, $value] = explode('=', $cookie);

$data[trim($name)] = trim($value);

}

$resp = $this->jar->fromArray($data, $base_url);

return $resp;

} catch (Exception $e) {

$this->output->writeln('验证⽤户Cookies发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

*

获取产品的信息

* @return array

*/

private function getProduct()

{

try {

fwrite(STDOUT, '请输⼊你的产品的URL路径:');

$url = trim(fgets(STDIN));

$args = explode('/', $url);

$product_id = array_pop($args);

$sku = $this->getProductSku($product_id);

$this->output->writeln("-------------获取产品SKU信息成功-------------");

return $sku;

} catch (Exception $e) {

$this->output->writeln('获取产品信息发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

* sku

获取产品的列表

* @param $product_id

* @return array

*/

private function getProductSku($product_id)

{

try {

$skuInfoUrl = "/item/skuInfo?itemCode={$product_id}&province=&city=&area=&latitude=&longitude=";

$response = $this->client->request('GET', $skuInfoUrl, [

'timeout' => 3.14,

'verify' => false,

]);

$content = $response->getBody()->getContents(); //

获取响应体,对象

$content = json_decode($content, JSON_UNESCAPED_UNICODE);

$skus = [];

foreach ($content['data']['skus'] as $sku) {

$item['skuCode'] = $sku['skuCode'];

$item['stock'] = $sku['stock'];

$item['salePrice'] = $sku['salePrice'];

$item['saleSiteId'] = $sku['saleSiteId'];

$item['saleSiteType'] = $sku['saleSiteType'];

$item['itemCode'] = $sku['itemCode'];

$item['description'] = $sku['saleAttributes'];

$item['activityPrice'] = $sku['activityPrice'];

$skus[] = $item;

}

return $skus;

} catch (Exception $e) {

$this->output->writeln('获取产品SKU发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

* cookies

获取的账号信息以及个⼈地址

* @param $cookies

* @return mixed

*/

public function getUserInfo()

{

try {

//

个⼈中⼼

$centerUrl = '/member/center?';

$response = $this->client->request('GET', $centerUrl, [

'timeout' => 3.14,

'verify' => false,

'cookies' => $this->cookies,

// 'debug' => true, //

调试

]);

$content = $response->getBody()->getContents(); //

获取响应体,对象

$content = json_decode($content, JSON_UNESCAPED_UNICODE);

$this->output->writeln("-------获取⽤户信息成功-------");

return $content['data'];

} catch (Exception $e) {

$this->output->writeln('获取⽤户信息发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

*

获取⽤户地址

*/

private function getUserAddress()

{

try {

$url = '/addressBook/list';

$response = $this->client->request('POST', $url, [

'timeout' => 3.14,

'verify' => false,

'cookies' => $this->cookies,

// 'debug' => true, //

调试

]);

$content = $response->getBody()->getContents(); //

获取响应体,对象

$centerContent = json_decode($content, JSON_UNESCAPED_UNICODE);

$this->output->writeln("-------获取⽤户地址成功-------");

return $centerContent['data'];

} catch (Exception $e) {

$this->output->writeln('获取⽤户地址列表发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

*

设置需要购买的数量

* @return int

*/

private function getInputCount()

{

try {

$result = false;

do {

do {

fwrite(STDOUT, '请输⼊你需要购买的数量:');

$count = trim(fgets(STDIN));

if (is_numeric($count) && $count != 0 && $count != '') {

$result = true;

$this->count = intval($count);

return intval($count);

}

$this->output->writeln('请输⼊⼀个正确的数字');

} while ($result == false);

} catch (Exception $e) {

$this->output->writeln('抢购数量发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

*

选择⽤户的地址

* @return int|string

*/

private function selectUserAddress()

{

try {

$this->output->writeln('-------------⽤户地址列表-------------');

foreach ($this->address as $key => $address) {

$item = [];

if ($address['isDefault'] == 1) $item[] = '《默认地址》';

unset($address['id']);

unset($address['latitude']);

unset($address['longitude']);

unset($address['source']);

unset($address['uicUserId']);

unset($address['is_default']);

foreach ($address as $name => $value) {

$item[] = $value;

}

$item = implode(' ', $item);

$this->output->writeln("地址-序号:{$key} -> {$item}");

}

//

验证输⼊的序号是否合法

$result = false;

do {

fwrite(STDOUT, '请选择⽤户序号的地址:');

$input = trim(fgets(STDIN));

//

⾮法输⼊

if ($input > count($this->address) || $input < 0) continue;

$result = true;

$this->current_address = $input;

return $this->current_address;

} while ($result == false);

} catch (Exception $e) {

$this->output->writeln('选择⽤户地址发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

}

/**

* sku

选择产品的

* @return int|string

*/

private function selectProductSku()

{

try {

$this->output->writeln('-------------SKU列表-------------');

$lists[] = [

'序号', 'SKU', '库存', '价格', '描述',

];

foreach ($this->skus as $key => $sku) {

$item = [];

$item['key'] = $key; //sku

$item['skuCode'] = $sku['skuCode']; //sku

$item['stock'] = $sku['stock']; //

库存

$item['salePrice'] = $sku['salePrice'] / 100; //

价格

foreach ($sku['description'] as $description) {

$item['description'] = implode(',', [$description['key'], $description['value']]); // sku

描述

}

$lists[] = $item;

}

foreach ($lists as $rows) {

foreach ($rows as $row) {

$this->output->write($row . "tt");

}

$this->output->write("n");

}

//

验证输⼊的序号是否合法

$result = false;

do {

fwrite(STDOUT, '请选择产品SKU序号的序号:');

$input = trim(fgets(STDIN));

//

⾮法输⼊

if ($input > count($this->address) || $input < 0) continue;

$result = true;

$this->current_sku = $input;

return $this->current_sku;

} while ($result == false);

} catch (Exception $e) {

$this->output->writeln('发⽣错误,程序即将退出,错误原因:' . $e->getMessage());

exit;

}

}

/**

*

设置开始抢购的时间

* @return false|int

*/

private function getInputStartTime()

{

try {

$result = false;

$result = false;

do {

fwrite(STDOUT, '请输⼊开始抢购的时间:');

$time = trim(fgets(STDIN));

$time = strtotime($time);

if (time() < $time) {

$result = true;

$this->start_time = $time;

return $time;

}

$this->output->writeln('请输⼊⼀个正确的时间范围');

} while ($result == false);

} catch (Exception $e) {

$this->output->writeln('抢购开始时间发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

* order

⽣成提交订单的

* @return mixed

*/

private function getConfirmToken()

{

// addressId: 2891060

//itemReqStr: [{"count":1,"saleSiteId":403,"skuCode":"127"}]

try {

$this->output->writeln('-------------正在⽣成订单Token-------------');

$url = '/order/confirm';

$response = $this->client->request('POST', $url, [

'timeout' => 3.14,

'verify' => false,

'cookies' => $this->cookies,

'form_params' => [

'addressId' => $this->address[$this->current_address]['id'],

'itemReqStr' => json_encode([[

'count' => $this->count,

'saleSiteId' => $this->skus[$this->current_sku]['saleSiteId'],

'skuCode' => $this->skus[$this->current_sku]['skuCode'],

]]),

]

]);

$content = $response->getBody()->getContents();

$content = json_decode($content, JSON_UNESCAPED_UNICODE);

$token = $content['data']['orderToken'];

$this->orderToken = $token;

$this->output->writeln("-------------订单Token⽣成成功,Token值为:{$token}-------------");

return $token;

} catch (Exception $e) {

$this->output->writeln('⽣成订单Token发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

/**

/**

*

提交订单信息

*/

private function submitOrder()

{

try {

$this->output->writeln('-------------提交订单中-------------');

$url = '/order/submit';

$data['token'] = $this->orderToken;

$data['addressId'] = $this->address[$this->current_address]['id'];

$data['deliveryRemark'] = $this->orderToken;

$data['coupons'] = [];

$data['orderFee'] = $this->skus[$this->current_sku]['activityPrice']; //

价格

$data['orderFrom'] = 1;

$data['itemList'] = [

[

'skuCode' => $this->skus[$this->current_sku]['skuCode'],

'siteId' => $this->skus[$this->current_sku]['saleSiteId'],

'count' => $this->count,

'remark' => '[]',

]

];

$data['siteRemarks'] = [

[

'siteId' => 13,

'remark' => '',

]

];

$response = $this->client->request('POST', $url, [

'timeout' => 3.14,

'verify' => false,

'cookies' => $this->cookies,

'json' => $data,

]);

$content = $response->getBody()->getContents();

$content = json_decode($content, JSON_UNESCAPED_UNICODE);

$this->output->writeln("-------------提交订单完成,当前订单状态:{$content['msg']}-------------");

} catch (Exception $e) {

$this->output->writeln('提交订单发⽣错误,错误原因:' . $e->getMessage());

exit;

}

}

}