这个数据采集项目本来是一个外包项目,做完了一阵子老板不要了…所以就把它开源了…
项目地址:https://github.com/yujunjiex/AHSSpider
数据分析结果请见:https://yujunjiex.gitee.io/2019/10/01/爱回收二手平台数据分析
如何获得一件商品的回收报价?
以macbook pro2017 13寸的二手报价过程为例
- 来到笔记本(laptop)页面,选中苹果(b52)
找到macbook pro2017 13寸并进入商品界面(/product/{商品id})
根据系统给出的一系列属性进行选择,其中属性分为
base-property
(处理器,显卡等重要信息),function-property
(是否机身进水,严重维修,部件损坏等信息),还有这件商品中没有的quick-property
(使用情况——用于快速报价的一个属性)点击「立即估价」得到商品报价信息(inquery/{inquery_key})
我们需要哪些信息?
- 一件商品的「商品id」用于定位页面
- 商品页面的属性信息如何获取
- 如何post选择的属性
- 最后的报价信息如何获取
开始分析
商品的「商品id」如何获取
在laptop/b52
列出的「笔记本电脑」「苹果」页中的每个li
中都有这个商品页的地址(包含id)
所以我们只需对品牌信息进行分页爬取,就能获得每一页中的商品地址(商品id)
商品页面的属性信息
同样页面元素中也有相关的属性信息
但有没有相关的api提供呢?毕竟有api谁还会去解析html页面嘛,用chrome
自带的调试工具选中XHR
查看异步请求果然有相关的api提供!
这时我们获取到了所有属性的api:
1 | # 属性api |
如何post请求
在这个问题之前还有一个问题,就是如何构造这个属性选择的列表?
数据采集过程是自动化的,应根据拿到的属性提前给与属性该如何选择,所以我们需要知道所有商品的属性并集,并提供属性的选择方案。
比如我需要拿到「笔记本电脑」的属性并集的话,我可以获取任意个笔记本电脑商品的属性,放入到set
中,最后拿到的就是属性的并集。
最后获取到「笔记本电脑」的属性有:
{‘固态硬盘’, ‘显卡’, ‘开机运行’, ‘边框背板’, ‘颜色’, ‘键盘’, ‘屏幕显示’, ‘购买渠道’, ‘屏幕类型’, ‘国内保修情况’, ‘机械硬盘’, ‘内存’, ‘处理器’, ‘屏幕外观’}
我们就可以根据自己需要对「笔记本电脑」的属性设置选择的默认值。
回到如何post请求上来
先找到「立即估价」这一元素的逻辑,可以看到是跳转到了userinquiry/createnew.html
这个页面。但请求前后的页面不一致,怀疑是重定向
所以我们再通过fiddler抓包分析到post请求的构造
可以看到这个post请求得到的json数据中有redirectUrl
也就是最后的报价信息!但这个请求中的productIds、Ppvids、PhenomenonItemIds和IsEnvironmentRecycling又如何获取呢?
productIds猜测是商品id,Ppvids猜测是属性选择的数组,经过实际分析也证实了猜测。
那其他两个参数呢,这时候只能到「立即估价」的click事件里去看看了= =,经过分析找到了这一段js代码
1 | $submit.on("click", function(d) { |
o.PhenomenonItemIds = t(),o.IsEnvironmentalRecycling = i(),
我们分别找到对应的函数
1 | function t() { |
看起来就是t()获取function-property
选择的数组,i()获取是否有属性为isenvironmentalrecycling
的选中(后面发现isenvironmentalrecycling只有在function-property有选择的时候才为true)
而function-property
属性都是商品已经严重损坏的一些情况,我们这里默认不选择即可。所以我们只需要获取productIds
和通过属性api构造Ppvids
数组就能得到报价信息。
最后的报价信息如何获取
通过post拿到的redirectUrl
即商品报价页
通过分析可以获取报价的api(inquery_key即redirectUrl
中最后面的数字)
1 | "https://www.aihuishou.com/portal-api/inquiry/{inquery_key}" |
测试
测试通过,接下来就是编码任务了!(中间还有一堆的坑= =)