ramsayleung / jd_spider

Two dumb distributed crawlers
https://ramsayleung.github.io/zh/post/2017/jd_spider/
727 stars 208 forks source link

同一个商品多个sku,如何获取所有sku的信息 #14

Closed caydenprivate closed 6 years ago

caydenprivate commented 6 years ago

类似于图书不存在多种规格,但是手机类商品,同一个商品有多种规格,查看页面,多个规格是通过js动态加载的,默认情况下每一页加载60个商品,但是每个商品有多个单品,现在的爬虫只能获取60个商品,但是商品下的其他单品爬取不到,有没有什么解决办法呢

ramsayleung commented 6 years ago

要不来个具体的例子,比如商品的网页,可以具体分析一下?

caydenprivate commented 6 years ago

https://list.jd.com/list.html?cat=9987,653,655 比如手机这个分类,默认显示每页显示60条商品,第一个商品默认选中的sku_id=5181386的手机,但是该商品有四个规格,爬取的时候如何获取另外3个规格的数据呢 image

ramsayleung commented 6 years ago

其实,这里不只是3个规格,应该是共有12个规格,可以通过class="choose-attrs"这个html 标签来获取所有的标准.

jd

caydenprivate commented 6 years ago

查看了一下页面源码,class="choose-attrs"下面只有可见的这7个sku的信息,不论点到哪个sku的详细信息,永远都是这7个sku

ramsayleung commented 6 years ago

这个有什么问题么?商品sku的页面本来就是异步请求加载的,我说12个是因为4X3 个规格,但是它可能会有些组合会无货的.是7个也没有什么问题~

caydenprivate commented 6 years ago

找到解决办法了,页面中有一段js,包含suo所有sku的信息,然后可以通过正则表达式取这一段js的内容 colorSize: (.+?),,然后就可以获取到所有sku的信息了

image

ramsayleung commented 6 years ago

我觉得嘛,这样的解决方法不够通用,除非你可以找到通用的请求后台的方式.不然你的解决方法只适用于当前的手机.换个商品不一定有phoneNetworkcolorSize 的属性,例如换成奶粉就有不同重量的规格,而不是不同颜色.

caydenprivate commented 6 years ago

有三种情况

  1. 一个商品只有一个sku
  2. 一个商品由一个属性组n个属性确定n个sku
  3. 一个商品由两个属性组分别有n个属性和m个属性,确定n*m个sku

第一种情况直接取值,第二种情况可以从class="choose-attrs"中取属性也可以从js中取colorSize属性,第三种情况目前观察只在手机和宽带这两个分类下面出现,从js取colorSize属性 还没发现除这三种情况之外的情况,而且大多数商品属于第二种情况,少数第一种,第三种最少

ramsayleung commented 6 years ago

所以通过 class="choose-attrs" 不就可以涵盖三种情况么,因为如何是什么规格,最终都是变成html 展示成不同的选项,只需要遍历html就可以找到所有的sku 了~

caydenprivate commented 6 years ago

第三种情况下,通过class="choose-attrs"只能拿到n+m个sku的信息,剩下的几个sku仅仅只在js里面有信息 image

ramsayleung commented 6 years ago

是的,通过class="choose-attrs"是只能获取n+m 个sku, 因为显示只是显示n+m个规格. 但是使用 class=choose-attrs 的方式也是可以获取n*m 个sku 的,只是不是像你这样一次性通过js 获取全部,而是第一获取n+m 个商品,然后第二次获取n+m 商品,一直到n+m 次获取n+m 商品, 例如第一次从"魅海蓝"获取7个商品,然后就有了7个不同的sku, 可以在通过7个sku 继续获取其他的sku, 广度遍历,很快就会把所有的sku 遍历完.诚然, 这种方式对比你的方式来得不够直接,需要多次遍历(当然重复的sku 会被过滤掉),但是这样的方法足够通用,因为无法确定是否只有PhoneNetworkcolorSize 这两个规格.

caydenprivate commented 6 years ago

一开始我也以为可以通过第一个n+m获取到不同的n+m个sku,但实际上,不管是第几次,始终都只有一开始的这几个sku,这一块的数据是定死的

ramsayleung commented 6 years ago

well, 那就用你的解决方法~

caydenprivate commented 6 years ago

👌

ditingdapeng commented 5 years ago

你好,请问这个sku的接口是什么呢