嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

周梦康 发表于 2017-02-16 1159 次浏览

看到微博上有 aj13 发售,虽然不是我最最喜欢的款,也是非常喜欢的了!准备出手!

Air Jordan XIII 的设计灵感来自 MJ 黑猫一般的天性。1997-1998 年赛季,MJ 穿上这款由汀克·哈特菲尔德打造的设计,完成了职业生涯第六冠的拼夺。在此期间,该设计推出了多款芝加哥灵感配色。如今,近二十年过去,Air Jordan XIII 以元年配色重归大众视野。

 

2 月 18 日在 Nike.com 推出男码和儿童码。


http://www.nike.com/cn/zh_cn/launch/c/2017-02/air-jordan-13-retro-og-white-red

AIR JORDAN 13 RETRO OG 'WHITE/RED'

官网会有发售,在虎扑上问了下老司机,都说基本不可能抢到,所以我打电话咨询 nike ,客服给我发邮件告知了一系列实体店的电话号码。

第一个号码是住户,直接给我挂了,估计不止我一个人骚扰到这位大妈了;

第二个号码直营店,但不会发售,可以去中关村欧美汇和蓝色港湾附近的一家店看看;

第三个号码是折扣店,不会发售,只知道官网有售,其他地方不知道;

第四个号码是折扣店,这家我知道,毕竟常去,哈哈;

第五个号码是直营店,但是告诉直营店不会发售,只有合作店铺才会发售;

第八个就是欧美汇,电话无人接听,周六直接过去考察???

后面电话懒得打了,看着就不像有发售的。


在虎扑求助,也没人告诉我哪里有卖的,反正无聊,要不自己写个脚本来抢吧,正好明天早上2月17号有一双aj7发布,可以试试我的脚本。很久没写博客了,反正无聊记录下那些骚动的青春?

说实话,我很少搞爬虫的事,下面可能比较笨。

说干就干,官方没有放出抢购页面,估计会9点左右直接售卖列表中放出,所以,我只需要不停的刷那个列表,肯定会出来。

我打开了 http://store.nike.com/xxx 尝试去找一个 HXR 请求来来获取商品列表,没有找到。直接抓取这个页面试试。

  1. 直接使用wget没问题,我在服务器上wget执行也是一样,没问题。这里没有 cookie 却没有问题。但是考虑后面我需要自动购买,所以,我还是放弃了纯 shell 命令的 wget

  2. 使用file_get_contents却获取不到内容。

  3. 使用curl抓取被拦截

  4. 再使用fsockopen 去掉 cookie 就和 curl 一样的结果

nike_Cart_hanleJCartResponse({
	"exceptions": [{
		"property": "catalogRefId",
		"errorcode": "noItemsToAddInStock",
		"message": "Sorry, this item isn't available anymore because other shoppers added it to their carts first. But if they don't check out in the next few minutes, you've still got a chance. Please try again shortly. [Code: 010N-1127140]"
	}],
	"status": "failure",
	"order": {
		"id": "dummy",
		"objType": "order",
		"itemQuantity": 0
	}
});

为什么这个地址我直接扔在地址栏是不会被拦截呢,首次访问的时候也没有 cookie 啊,哪里没模拟到呢?

最后就用这段代码吧,先

$fp = fsockopen("store.nike.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)\n";
} else {
    $out = "GET /cn/zh_cn/pw/%E7%94%B7%E5%AD%90-jordan-%E7%AF%AE%E7%90%83-%E9%9E%8B%E7%B1%BB/7puZofqZ8r1Zoi3 HTTP/1.1\r\n";
    $out .= "Host: store.nike.com\r\n";
    $out .= "Pragma: no-cache\r\n";
    $out .= "Cache-Control: no-cache\r\n";
    $out .= "Upgrade-Insecure-Requests: 1\r\n";
    $out .= "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\n";
    $out .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";
//    $out .= "Accept-Encoding: gzip, deflate, sdch\r\n"; 不然没法解析 gzip 压缩之后
    $out .= "Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2\r\n";
    $out .= "Cookie: xxxx\r\n";
    $out .= "Connection: close\r\n\r\n";

    stream_set_timeout($fp, 4);
    fwrite($fp, $out);
    file_put_contents("a.log","");
    while (!feof($fp)) {
        $data = fgets($fp,1024);
        file_put_contents("a.log",$data,FILE_APPEND);
    }
    fclose($fp);
}

里面的 cookie 是我匿名登录的。

好,获取到返回的结果之后就是解析html了

$fp = fsockopen("store.nike.com", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)\n";
} else {
    $out = "GET /cn/zh_cn/pw/%E7%94%B7%E5%AD%90-jordan-%E7%AF%AE%E7%90%83-%E9%9E%8B%E7%B1%BB/7puZofqZ8r1Zoi3 HTTP/1.1\r\n";
    $out .= "Host: store.nike.com\r\n";
    $out .= "Pragma: no-cache\r\n";
    $out .= "Cache-Control: no-cache\r\n";
    $out .= "Upgrade-Insecure-Requests: 1\r\n";
    $out .= "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\n";
    $out .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";
//    $out .= "Accept-Encoding: gzip, deflate, sdch\r\n"; 不然没法解析 gzip 压缩之后
    $out .= "Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2\r\n";
    $out .= "Cookie: xxxx\r\n";
    $out .= "Connection: close\r\n\r\n";

    stream_set_timeout($fp, 4);
    fwrite($fp, $out);
    $data = "";
    while (!feof($fp)) {
        $data .= fgets($fp,1024);
    }
    fclose($fp);
}

file_put_contents("a.log",$data);

include "SimpleHtmlDom.php";

$tmp = explode("<!DOCTYPE html>",$data);
$html = "<!DOCTYPE html>".$tmp[1]; // 去掉返回的 http 头信息

$dom = new simple_html_dom($data);
$res = $dom->find(".exp-product-wall",0);



foreach($res->children as $child) {
    $name = $child->find(".product-name p",0)->innertext;
    echo $name;

    if ($name == "Air Jordan XXXI") {
        $url = $child->attr["data-pdpurl"];

    }
}

这样终于获取到这个列表下的17双鞋了

下面要做的就是自动提醒和自动添加到购物车了。

作为一个商务办公人士,我怎么可能不用钉钉呢?钉钉推出了机器人功能,自动提醒。我只需要简单调用它的api即可。

在上面的基础上简单修改下代码就可以了。

foreach($res->children as $child) {
    $name = $child->find(".product-name p",0)->innertext;

    if ($name == "Air Jordan XXXI") {
        $url = $child->attr["data-pdpurl"];
        $msg = sprintf("\n报告康哥\n%s 已经开始发售\n购买链接:%s",$name,$url);
        sendMessage($msg);
    }
}

exit;

function sendMessage($message)
{
    $data = [
        "msgtype" => "text",
        "text"    => [
            "content" => $message,
        ],
        "at"      => [
            "isAtAll"   => false,
        ],
    ];

    $context = stream_context_create(array(
        'http' => array(
            'method'  => 'POST',
            'header'  => "Content-Type: application/json",
            'content' => json_encode($data),
            'timeout' => 60,
        ),
    ));

    $url = "https://oapi.dingtalk.com/robot/send?access_token=xxx";
    file_get_contents($url, false, $context);
}

我在钉钉上跟自己发起一个群聊,然后给群聊添加一个机器人。

假设我要抢购Air Jordan XXXI,代码在服务器上扫,只要发现nike的工作人员发布了Air Jordan XXXI,我就能第一时间收到推送,马上去抢了。不过话说回来,这样的 app 是不是已经有了?

手机电脑双重保险,保证你收到通知,稳。

没错,看到这里,理性的朋友可能已经发现了,这其实是我受钉钉团队重托而精心打造的一篇推广软文。不仅我可以收到推送,只要加我好友,我拉你入群,大家都可以收到推送。

太晚了,明天再把自动加入到购物车弄了。

终于刷出来了,还好有提醒,并不是最新上架的就排在最上面

11点前终于抢到了

哈哈哈,爱不释脚。明天公司打球实战,求!不!要!踩!我!的!鞋!

分享到

评论列表

如果填写邮箱了,当我我回复您的时候会给您邮箱发送消息提醒,方便交流
提交 可以使用`xxxx`来插入简短的代码碎片
1楼 康哥 2017-02-17 01:05:44

好久没有折腾到这么晚了,也好久没有写博客玩了。

回复
2楼 康哥 2017-02-17 10:18:30

跟客服反馈电话有误之后,更新了下电话:北京市朝阳区工体北路三里屯路口太古里南区S8号楼二层 010-64168099

回复