教您使用java爬虫gecco抓取JD所有商品信息(三)

##详情页抓取 商品的基本信息抓取完成后,就要针对每一个商品的详情页进行抓取,能够看到详情页的地址格式通常以下:http://item.jd.com/1861098.html。咱们创建商品详情页的Bean:javascript

@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}。css

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

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

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

##json数据的元素抽取 商品的价格是经过ajax获取的,ajax通常返回的都是json格式的数据,这里须要将json格式的数据抽取出来。咱们先定义价格的Bean:github

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语法。ajax

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

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请求有两种主流方式:chrome

  • 一种是模拟浏览器将页面彻底绘制出来,好比能够利用htmlunit。这种方式存在一个问题就是效率低,由于页面中的全部ajax都会被请求,并且须要解析全部的js代码。gecco能够经过自定义downloader来实现这种方式
  • 还一种就是须要哪些ajax就执行哪些,这就要开发人员分析网页中的ajax请求,得到请求的地址,好比抓取JD的商品价格的地址@Ajax(url="http://p.3.cn/prices/mgets?skuIds=J_[code]")。并且这个地址以后可能会变。

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

下面说说怎么分析页面中的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提问,固然也能够在博客中留言。

相关文章
相关标签/搜索