java爬虫抓取动态网页(教您使用java爬虫geccogeccoJD商品信息商品信息)

优采云 发布时间: 2022-02-06 17:23

  java爬虫抓取动态网页(教您使用java爬虫geccogeccoJD商品信息商品信息)

  关于gecco爬虫框架

  不了解gecco的可以参考gecco的github主页。gecco 爬虫非常简单易用。有一篇文章文章《教你使用java爬虫gecco抓取京东商品信息》,使用的是传统的注解方式。建议在阅读本文章之前先了解前面的文章。这里我们介绍一下DynamicGecco方法,它比以前更简单。只需要3个品类,就可以把京东的所有产品都抢完。

  什么是 DynamicGecco

  DynamicGecco的目的是在不定义SpiderBeans的情况下实现爬取规则的运行时配置。实现原理是利用字节码编程动态生成SpiderBeans,通过自定义的GeccoClassLoader实现抓取规则的热部署。通常我们可以使用DynamicGecco来实现以下功能:

  规则定义

  爬虫的爬取规则,如matchUrl、csspath、ajax等,不需要使用注解注入SpiderBean,直接使用DynamicGecco定义。以下是京东全品抓取规则定义:

  public static void main(String[] args) {

//对应原来的Category和HrefBean类

Class category = DynamicGecco.html

.stringField("parentName").csspath("dt a").text.build

.listField("categorys",

DynamicGecco.html

.stringField("url").csspath("a").href.build

.stringField("title").csspath("a").text.build

.register).csspath("dd a").build

.register;

//对应原来的AllSort类

DynamicGecco.html

.gecco("http://www.jd.com/allSort.aspx", "consolePipeline", "allSortJsonPipeline")

.requestField("request").request.build

.listField("mobile", category)

.csspath(".category-items > div:nth-child(1) > div:nth-child(2) > div.mc > div.items > dl").build

.register;

//对应ProductBrief类

Class productBrief = DynamicGecco.html

.stringField("code").csspath(".j-sku-item").attr("data-sku").build

.stringField("title").csspath(".p-name> a > em").text.build

.stringField("preview").csspath(".p-img > a > img").image("", "data-lazy-img", "src").build

.stringField("detailUrl").csspath(".p-name > a").href(true).build

.register;

//对应ProductList类

DynamicGecco.html

.gecco("http://list.jd.com/list.html?cat={cat}&delivery={delivery}&page={page}&JL={JL}&go=0", "consolePipeline", "productListJsonPipeline")

.requestField("request").request.build

.intField("currPage").csspath("#J_topPage > span > b").text.build

.intField("totalPage").csspath("#J_topPage > span > i").text.build

.listField("details", productBrief).csspath("#plist .gl-item").build

.register;

//对应ProductDetail类

DynamicGecco.html

.gecco("http://item.jd.com/{code}.html", "consolePipeline")

.stringField("code").requestParameter.build

.stringField("title").csspath("#name > h1").text.build

.stringField("detail").csspath("#product-detail-2").build

.stringField("image").csspath("#spec-n1 img").image("d:/gecco/jd/img").build

.field("price", FieldType.type(JDPrice.class)).ajax("http://p.3.cn/prices/get?type=1&pdtk=&pdbp=0&skuid=J_{code}").build

.field("jdAd", FieldType.type(JDad.class)).ajax("http://cd.jd.com/promotion/v2?skuId={code}&area=1_2805_2855_0&cat=737%2C794%2C798").build

.register;

HttpGetRequest start = new HttpGetRequest("http://www.jd.com/allSort.aspx");

start.setCharset("GBK");

GeccoEngine.create

.classpath("com.geccocrawler.gecco.demo.jd")

.start(start)

.interval(2000)

.run;

}

  规则定义好后,就可以启动GeccoEngine了,和之前一样。可以看出,前面的例子定义了7个bean,但是这里只需要一个类。

  语法解释 JsonPipeline

  Pipeline 的写法也和以前不一样。因为是运行时生成的bean,所以定义的bean不能像以前那样直接使用。Gecco 会将所有 bean 转换为 JSONObject,并通过 json 操作获取捕获的信息。下面是DynamicJD定义的两条Pipeline:

  @PipelineName("allSortJsonPipeline")

public class AllSortJsonPipeline extends JsonPipeline {

public static List sortRequests = new ArrayList;

@Override

public void process(JSONObject allSort) {

HttpRequest currRequest = HttpGetRequest.fromJson(allSort.getJSONObject("request"));

JSONArray categorys = allSort.getJSONArray("mobile");

process(currRequest, categorys);

}

private void process(HttpRequest currRequest, JSONArray categorys) {

if(categorys == null) {

return;

}

for(int i = 0; i < categorys.size; i++) {

JSONObject category = categorys.getJSONObject(i);

JSONArray hrefs = category.getJSONArray("categorys");

for(int j = 0; j < hrefs.size; j++) {

String url = hrefs.getJSONObject(j).getString("url")+"&delivery=1&page=1&JL=4_10_0&go=0";

SchedulerContext.into(currRequest.subRequest(url));

}

}

}

}

  产品列表处理Pipeline,对应原ProductListPipeline

  @PipelineName("productListPipeline")

public class ProductListPipeline implements Pipeline {

@Override

public void process(ProductList productList) {

HttpRequest currRequest = productList.getRequest;

//下一页继续抓取

int currPage = productList.getCurrPage;

int nextPage = currPage + 1;

int totalPage = productList.getTotalPage;

if(nextPage newRule = DynamicGecco

.html(rule1.getName)

.gecco("https://github.com/xtuhcy/gecco", "consolePipeline")

.intField("fork").csspath(".pagehead-actions li:nth-child(3) .social-count").text.build

.removeField("star")

.loadClass;

//注册新规则

ge.register(newRule);

} catch(Exception ex) {

ex.printStackTrace;

} finally {

//规则更新完毕

ge.endUpdateRule;

}

  线下有规矩

  已经定义好的规则,我们可以下线如下:

  try {

//开始更新规则

ge.beginUpdateRule;

//下线之前的规则

ge.unregister(rule);

} catch(Exception ex) {

ex.printStackTrace;

} finally {

//规则更新完毕

ge.endUpdateRule;

}

  至此,爬虫规则的添加/修改/删除已经实现。您可以愉快地配置爬虫规则!

  完整的demo代码可以参考github上的源码,位于com.geccocrawler.gecco.demo.dynamic包中。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线