机器之心报道参与:思

今天 2 月 9 日新增病例 2653,虽然新增人数已经有所放缓,但随着返工人流的迁移,防护口罩仍然必不可少。

口罩要靠抢?这个 Python 爬虫帮你实时检测、快速下单

在开发者社区中,因为开发者很多都要前往北上广继续搬砖,那么怎样买到稀缺资源口罩就必须要考虑了。近日,cycz 在 GitHub 上开源了一份代码,它可以实时监测京东上的口罩是否有货,并在有货的时候实时下单并提醒。
项目地址:https://github.com/cycz/jdBuyMask
对于 jdBuyMask 项目,直观而言就是不停地刷某些商品,并且在有货的情况下自动下单。因为目前口罩是紧缺物资,为了防止哄抢,开发者将其设置为自动一次只买一件。我们试用的是 V3 版,其主要流程即先将口罩加入购物车,然后在检测有货的情况下立马下单。
我们选择了一款 KN95 口罩,并设置商品 id、地区 id、cookie 等参数后,就能够正常跑起来了:

我们可以看到爬虫会不停地刷新该商品状态,并尝试下单。我们也测试了第一版 jdBuyMask 与第二版,它们也是能跑起来的,如下所示在后来测试第一版时,程序表示该商品已下柜,我们在网页上刷新后得到的信息也是相同的。

口罩要靠抢?这个 Python 爬虫帮你实时检测、快速下单

口罩爬虫如何用
目前该项目一共有四个版本,其中三个版本为代码文件,还有一个直接是 EXE 可执行文件。如果读者用的 Win 系统,也可以直接运行 EXE 程序,只不过项目作者表示 EXE 更新频率会比代码慢一些。所有版本在下单后,都可以通过邮件或微信实时通知。
项目作者表示 V2 版程序分为正常模式与急速模式,其中正常模式会检测是否有货、是否下柜、加入购物车、查看购物车、下单;而急速模式会检查是否有货、加入购物车、下单。
项目作者表示,V3 版程序下单更快,因为它会提前将商品加入购物车,并减少提交订单的请求量,只要检测有货,就会立即下单。只不过,目前 V3 版程序只能自动监测单个商品。
在使用上,最重要的就是获取商品的各种参数了,剩下的步骤都可以交给爬虫。除了配置通知方式,例如下图的邮件地址、方糖微信推送秘钥,配置爬虫还需要商品「URL」及网页 cookie。如下所示为第一版 jdBuyMask 的配置信息,后面我们会介绍如何获取商品「URL」及 cookie。

口罩要靠抢?这个 Python 爬虫帮你实时检测、快速下单

对于 jdBuyMask V2 及 V3,它们的配置都是从 configDemo.ini 中提取的。稍微有些不一样的是,买方地区 ID「area」和商品 ID「skuid」都需要从 Request URL 中提取。

口罩要靠抢?这个 Python 爬虫帮你实时检测、快速下单

获取购买参数
其它参数都是个人信息,按照自己的理解就能完成。现在,我们需要在 JD 网站上获取 Request URL 与 cookie。如果读者们用的是 Chrome 浏览器,那么进入开发者界面,Win 是按 F12,MacOS 是进入「检查」。
在「Network」选项中可以通过关键词「stock」进行筛选,然后就能看到下图的 Request URL 了,它就是我们需要的。

口罩要靠抢?这个 Python 爬虫帮你实时检测、快速下单

注意在 Request URL 中,skuID 表示商品 ID,area 表示地区代码,它们都是爬虫需要的参数。除此之外,如果我们进入「我的订单」,根据关键字「list.action」可以筛选出对应的 cookie。

口罩要靠抢?这个 Python 爬虫帮你实时检测、快速下单

最后,将这些参数填入到对应的地方,我们就能成功跑起来了。
爬虫代码
项目作者表示,下单的部分代码参考了 tychxn 之前的工作,其它主体代码都基于 requests 与 BeautifulSoup 两个库完成。项目作者在主要的函数及语句都写了注释,因此也方便我们修改源代码。
例如检查是否有货的代码,它主要在页面中查找是否存在「无货」这个关键词。

    '''      检查是否有货      '''      def check_item_stock(itemUrl):          response = session.get(itemUrl)          if (response.text.find(' 无货 ') > 0):              return True          else:              return False

勾选购物车中的商品主要通过 Post 完成,添加商品到购物车通过 Get 完成。

    '''      添加商品到购物车      '''      def add_item_to_cart(sku_id):          url = 'https://cart.jd.com/gate.action'          payload = {              'pid': sku_id,              'pcount': 1,              'ptype': 1,          }          resp = session.get(url=url, params=payload)          if 'https://cart.jd.com/cart.action' in resp.url:  # 套装商品加入购物车后直接跳转到购物车页面              result = True          else:  # 普通商品成功加入购物车后会跳转到提示 " 商品已成功加入购物车!" 页面              soup = BeautifulSoup(resp.text, "html.parser")              result = bool(soup.select('h3.ftx-02'))  # [    ### 商品已成功加入购物车!    ]          if result:              logger.info('%s  已成功加入购物车 ', sku_id)          else:              logger.error('%s 添加到购物车失败 ', sku_id)

总体而言,项目作者对 requests 与 BeautifulSoup 非常熟悉,有很多代码与方法都可以借鉴。当然,我们也可以根据自己的需求改一些方法,例如验证码的识别模块,更稳定的订单提交方式等等。
随着这两天返程高峰的出现,公共场所需要更多的防护,各大平台每天也只会放出少量口罩资源。借助爬虫监控口罩也许是程序猿擅长的方式,但是我们也应该注意够用就行,把更多机会让给更需要的人。

本 文为机器之心报道,**转载请联系本公众号获得授权 。**

✄------------------------------------------------加入机器之心(全职记者 / 实习生): hr@jiqizhixin.com 投稿或寻求报道:content @jiqizhixin.com 广告 & 商务合作: bd@jiqizhixin.com