Python爬虫实战:京东拍拍验机(帮你买到最完美的二手iPhone)

网站介绍&使用痛点

  如图1所示,京东拍拍二手于近期上线了一个新平台:拍拍验机,顾客可以通过手机京东客户端,在拍拍验机上挑选购买心仪的二手电子产品(目前均为固定品牌的手机,如二手小米8、二手iPhone 7 Plus)。

图1 拍拍验机主页示意图

  在首页,我们可以对手机进行筛选,比如笔者目前倾向于购买二手iPhone 7 Plus 128G 国行,那么就选择“苹果”->“苹果7P”->筛选“国行”和“128G”,如图2所示。确定后下拉页面,就都是符合筛选条件的手机了。

图2 拍拍验机筛选示意图

  但是,在下拉查看比较手机的过程当中,笔者发现符合筛选条件的手机太多太多了(实测大概400部左右),如果每一个手机都点进去查看对比的话,要把所有手机看一遍,将会花费大量时间,而且往往之前看中的手机再回过头来看,已经显示卖出,从而错失良“机”。此外由于app端服务器不稳定的原因,点击返回键常常显示“加载失败”,导致一切从头开始,需要额外浪费时间再下拉到刚刚浏览的地方,效率十分低下

  当在浏览过程中,看到心仪的手机,点击进去查看手机的详细介绍,会发现有很多的关键参数,比如电池电量、是否过保以及手机各项详细检测情况,如图3所示。如果我们能针对这些参数进行自主筛选,那么就可以迅速排除掉成百上千部手机中的绝大多数,“取其精华,去其糟粕”,只留下少量的“精品”进行挑选,效率将大大提高

图3 手机详细介绍示意图

  但是网站提供的筛选条件少得可怜,只有“价格”、“渠道”、“内存”三个筛选条件,既然如此,我们就要自己动手丰衣足食了

网站分析

  在浏览拍拍验机的主页后,我们发现它一次只会加载20部手机信息,并且加载的方式不是翻页,而是将页面滑动到底部,那么爬取静态网页数据的那一套方法就不能用在现在这种动态网页上(静态网页用Chrome浏览器右键“查看网页源代码”就能看到所有的网页数据,但是动态网页用这种办法是看不到的),这对获取新增的手机数据带来了困难。这里使用Chrome浏览器的“检查”功能解析AJAX动态加载地址,进而找到加载的数据。

  使用Chrome浏览器打开拍拍验机的主页,页面任意处右键,单机“检查”-> Network-> Ctrl + R刷新,每当滑动网页页面到底部时,Network下方会出现新加载的内容,单击 JS,单击左侧的一个_JPx(最好是选最底部的),单击 Headers,可以看到Request URL,如图4所示,后面要用到。注意链接里必须包含order=2_1,因为在实践中发现有些链接包含的是order=4_2,包含order=4_2的链接不是我们所需要的。

图4 寻找Request URL示意图

  可以发现,每当网页下拉加载新的手机数据的时候,JS里的_JPx就会增加一项,每次下拉刷新得到的新数据就是请求了

https://bizgw.jd.com/app/inspected/v1/list?pageSize=20&pageNo=1&brand=Apple&model=iphone7%20plus&order=2_1&buychannel=%E5%9B%BD%E8%A1%8C&capacity=128g&callback=__jp7

这个网页的json数据。单击Preview,可以看到json数据的结构,如图5所示。

图5 json数据的结构

  其中,我们可以看到新加载的每一个手机的唯一的"commodityId",后面要用到。将网页一直向下拉,JS中的_JPx就会一直增加,直到网页拉到底。如图6所示,可以看到_JPx增加到_JP22,_JP7到_JP22中就包含了所有的手机的"commodityId"。之后就需要通过Python爬虫将所有的"commodityId"收集起来。

图6 所有JS示意图

  接着点击进入任意一个手机的详细介绍页面,同样的方法,我们找到商品详情介绍页面的Request URL,详情介绍页面的数据就是请求了

https://bizgw.jd.com/commodityInspected/view?callback=jQuery34005582774663554724_1558160057557&commodityId=5583330&optSource=3&_=1558160057558

这个网页的json数据,如图7所示。

图7 寻找Request URL示意图

  在Preview中可以看到json数据的结构,包括保修期、电池电量、验机报告等详细检测数据,甚至能看到网页中看不到的信息,比如“验机中心”,如图8所示。

图8 单个商品json数据的结构

  通过Python爬虫,根据单个商品json数据的结构中的各种详细参数进行筛选,就能迅速排除掉大量干扰项,达到“取其精华,去其糟粕”的目的了。

项目实施

1. 爬取commodityId

1.1 失败的爬取思路

  通过分析,我们得到_JP7到_JP22包含了所有的手机的"commodityId"。那么就采用常用的requests.get()的方法,通过for循环,将每一个_JPx里的所有"commodityId"爬取出来保存到一个列表中,具体实现代码如下:

#-*- coding: utf-8 -*-
import requests
import re

#定义函数scrapy
def scrapy(link):
    headers = {
   
        #User-Agent和Referer的信息在Network->Headers->Request Headers
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
        'Referer':'https://paipai.m.jd.com/direct/?lng=119.954575&lat=31.686691&un_area=12_978_4459_53900&sid=b4d89db2c431e6c9631e9859ecdc099w&_ts=1557926133167&utm_source=iosapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=CopyURL&ad_od=share&ShareTm=kL%2BfusKf1qywVd%2BwTkAVtGYRXA2gzBQqFj4A0YuGC1teMZhlGn5CDqBdFZvEgw8/2zhgK18/FX3A93HO04B6bPi7qv8sqdX5i/bUuilkbnOp3GDR%2BoHeKPmG1hagOq5B0WaZTCW%2B7KvJdTxfEYpNNpGoA%2BsAMlUKlUnkVPBzD2g='
    }
    r = requests.get(link, headers=headers)
    return(r.text)

#将_jp7到_JP22的所有Request URL保存到一个列表中
Req_URL = []
for i in range(7, 23):
    Req_URL.append('https://bizgw.jd.com/app/inspected/v1/list?pageSize=20&pageNo=1&brand=Apple&model=iphone7%20plus&order=2_1&buychannel=%E5%9B%BD%E8%A1%8C&capacity=128g&callback=__jp'+str(i))

#将_jp7到_JP22中的的所有commodityId保存到一个列表中
all_Id = []
for i in Req_URL:
    m_findall = []
    html = ""
    html = scrapy(i)
    m_findall = re.findall(r'"commodityId":.{7}', html)#目前网站上机器码暂为7位数
    for id in m_findall:
        all_Id.append(id[-7:])

通过上述代码,就可以将所有的商品ID储存到列表all_Id当中,但是上述代码有两个问题:
  1. 运行代码后,发现每一个_JPx中的商品Id都是相同的,原因尚不清楚;
  2. 拍拍验机平台的手机数量是实时刷新的,现在我们看到的是所有商品Id保存在_JP7到_JP22,也许一小时后就变成_JP8到_JP30。

1.2 改进后的巧妙的爬取思路

  上述两个问题,第二个问题还好解决,但是第一个问题百思不得其解,涉及比较深入,对于笔者这种学习Python爬虫不足一月的人来说很难解,于是乎转而在Request URL上动心思。原版的Request URL为:

https://bizgw.jd.com/app/inspected/v1/list?pageSize=20&pageNo=1&brand=Apple&model=iphone7%20plus&order=2_1&buychannel=%E5%9B%BD%E8%A1%8C&capacity=128g&callback=__jp7

笔者将此链接进行一定的删改,发现并不影响request.get()的结果,于是乎将多余的删掉,得到:

https://bizgw.jd.com/app/inspected/v1/list?pageSize=20&brand=Apple&model=iphone7%20plus&order=2_1&buychannel=%E5%9B%BD%E8%A1%8C&capacity=128g

此时能爬取出20个商品ID。这时发现是不是pageSize=20限制了爬出的ID数量?遂改成pageSize=10000,神奇的事情发生了,400多个商品ID被一次全部爬出!实现代码如下&#x

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
测试 003版 注意: 请输入抢拍商品的URL:先选择抢拍商品,然后复制地址栏中的地址,然后粘贴到上面. 请输抢购时间:H(小时)M(分钟)S(秒) 你的系统时间应该和拍拍的系统时间一至,不一至的话抢拍时间肯定不准确,这样会造成严重失误. 运行时会初始为系统当前时间。 抢拍时最好先运行一个网页,且为登陆状态. 建义使用方法: 一)运行本程序 二)选择抢拍的商品并将地址粘贴至上面,依次输入此商品开始抢拍的小时,分钟,以及秒(必须有值,秒和分钟可以为零),持续时间为分钟,建义不要超过五分钟,默认为一分钟不能为零或负数。 三)点击点击 ,程序会打开一个网页,如果提示需要登陆时请登陆并且最好不要关闭此网页,在使用时最好打开一个已登陆的网页,并且可以随时的点击此按钮查看登陆状态(一般登陆半小时后将需要重新登陆),如果打开一个未显示的网页,可能你的抢拍商品地址有误 四)然后点击 ,这时程序会根据预设抢拍时间和系统时间的时间差以秒为单位倒记时并在等待时间信息框中显示,直至倒记数为零,然后开始抢拍,抢拍周期时间是预设持续时间并以倒记时方式在抢拍时间框中显示倒记数,当抢拍到时抢拍时间会停止显示并且打开一个抢拍商品的网页。 五)要随时注意你当前是否是登陆状态。并且在开始抢购前先查看连接。 作者:小贺 通信: msn:binhelive@hotmail.com QQ:258048565 我有开拍拍卖家和淘宝卖家,欢迎访问. 如有侵犯或违反你的相关权利请连系我,我会删除一切版本。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值