教您使用java爬虫gecco抓取JD全部商品信息(三) - ExceptionMapping的博客 - CSDN博客

详情页抓取

商品的基本信息抓取完成后,就要针对每个商品的详情页进行抓取,可以看到详情页的地址格式一般如下:http://item.jd.com/1861098.html。我们建立商品详情页的Bean:

@Gecco(matchUrl="http://item.jd.com/{code}.html", pipelines="consolePipeline")public class ProductDetail implements HtmlBean {     private static final long serialVersionUID = -377053120283382723L;     /**     * 商品代码     */    @RequestParameter    private String code;     /**     * 标题     */    @Text    @HtmlField(cssPath="#name > h1")    private String title;     /**     * ajax获取商品价格     */    @Ajax(url="http://p.3.cn/prices/get?skuIds=J_[code]")    private JDPrice price;     /**     * 商品的推广语     */    @Ajax(url="http://cd.jd.com/promotion/v2?skuId={code}&area=1_2805_2855_0&cat=737%2C794%2C798")    private JDad jdAd;     /*     * 商品规格参数     */    @HtmlField(cssPath="#product-detail-2")    private String detail;     public JDPrice getPrice() {        return price;    }     public void setPrice(JDPrice price) {        this.price = price;    }     public String getTitle() {        return title;    }     public void setTitle(String title) {        this.title = title;    }     public JDad getJdAd() {        return jdAd;    }     public void setJdAd(JDad jdAd) {        this.jdAd = jdAd;    }     public String getDetail() {        return detail;    }     public void setDetail(String detail) {        this.detail = detail;    }     public String getCode() {        return code;    }     public void setCode(String code) {        this.code = code;    }}

@RequestParameter可以获取@Gecco里定义的url变量{code}。

@Ajax是页面中的ajax请求,JD的商品价格和推广语都是通过ajax请求异步获取的,gecco支持异步ajax请求,指定ajax请求的url地址,url中的变量可以通过两种方式指定。

一种是花括号{},可以获取request的参数类似@RequestParameter,例子中获取推广语的{code}是matchUrl="http://item.jd.com/{code}.html"中的code;

一种是中括号[],可以获取bean中的任意属性。例子中获取价格的[code]是变量private String code;。

json数据的元素抽取

商品的价格是通过ajax获取的,ajax一般返回的都是json格式的数据,这里需要将json格式的数据抽取出来。我们先定义价格的Bean:

public class JDPrice implements JsonBean {     private static final long serialVersionUID = -5696033709028657709L;     @JSONPath("$.id[0]")    private String code;     @JSONPath("$.p[0]")    private float price;     @JSONPath("$.m[0]")    private float srcPrice;     public float getPrice() {        return price;    }     public void setPrice(float price) {        this.price = price;    }     public float getSrcPrice() {        return srcPrice;    }     public void setSrcPrice(float srcPrice) {        this.srcPrice = srcPrice;    }     public String getCode() {        return code;    }     public void setCode(String code) {        this.code = code;    } }

我们获取的商品价格信息的json数据格式为:[{"id":"J_1861098","p":"6488.00","m":"7488.00"}]。可以看到是一个数组,因为这个接口其实可以批量获取商品的价格。json数据的数据抽取使用@JSONPath注解,语法是使用的fastjson的JSONPath语法。

JDad的抓取类似,下面是Bean的代码:

public class JDad implements JsonBean {     private static final long serialVersionUID = 2250225801616402995L;     @JSONPath("$.ads[0].ad")    private String ad;     @JSONPath("$.ads")    private List<JSONObject> ads;     public String getAd() {        return ad;    }     public void setAd(String ad) {        this.ad = ad;    }     public List<JSONObject> getAds() {        return ads;    }     public void setAds(List<JSONObject> ads) {        this.ads = ads;    } }

学会分析ajax请求

目前爬虫抓取页面内容针对ajax请求有两种主流方式:

  • 一种是模拟浏览器将页面完全绘制出来,比如可以利用htmlunit。这种方式存在一个问题就是效率低,因为页面中的所有ajax都会被请求,而且需要解析所有的js代码。gecco可以通过自定义downloader来实现这种方式
  • 还一种就是需要哪些ajax就执行哪些,这就要开发人员分析网页中的ajax请求,获得请求的地址,比如抓取JD的商品价格的地址@Ajax(url="http://p.3.cn/prices/mgets?skuIds=J_[code]")。而且这个地址之后可能会变。%E3%80%82%E8%80%8C%E4%B8%94%E8%BF%99%E4%B8%AA%E5%9C%B0%E5%9D%80%E4%B9%8B%E5%90%8E%E5%8F%AF%E8%83%BD%E4%BC%9A%E5%8F%98%E3%80%82)

这两种方式都有各自的优缺点,gecco通过扩展都支持,本人还是更倾向于使用第二种方式。

下面说说怎么分析页面中的ajax请求,还是要利用chrome的开发者模式,network选项可以看到页面中的所有请求:

输入图片说明 可以看到请求的地址是:http://p.3.cn/prices/get?type=1&area=1_2805_2855&pdtk=&pduid=836516317&pdpin=&pdbp=0&skuid=J_1861098&callback=cnp。我们去掉其他参数只留下商品的代码,发现一样可以访问,http://p.3.cn/prices/get? skuid=J_1861098就是我们要请求的地址。

gecco的其他一些有用的特性

  • gecco支持页面中的定义的全局javascript变量的提取,如页面中定义的var变量。
  • gecco支持分布式抓取,通过redis管理startRequest实现分布式抓取。

源码

全部源代码可以在gecco的github上下载,代码位于src/test/java/com/geccocrawler/gecco/demo/jd包下。如果使用过程中发现任何bug欢迎Pull request,或者通过Issue提问,当然也可以在博客中留言。


Original url: Access
Created at: 2019-06-24 16:25:51
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论