您的位置:首页 > Web前端 > JavaScript

WebMagic学习-解析json

2016-11-05 00:00 141 查看

这篇文章要解决什么

当页面使用前端ajax方式渲染的页面数据时,页面会使用js请求ajaxUrl获取json格式数据时,然后再用js把数据解析并渲染到页面的指定位置上。

错误写法

当爬虫要住区ajaxUrl返回的json格式数据时,我当时是这样写的:

// 声明:下面这种方法是错误的。是我没有看官方demo的时候凭感觉写出的解析json数据的代码。
JsonPathSelector json = new JsonPathSelector(page.getRawText());
List<String> name = json.selectList("$.data.itemList[*].brand.name");
List<String> uri = json.selectList("$.data.itemList[*].brand.uri");

看了官方us.codecraft.webmagic.selector.JsonPathSelectorTest,才知道原来参数写错了。

正确写法

JsonPathSelector(String jsonPathStr)这个构造函数的参数是jsonPathStr,也就是提取规则的字符串

String select(String text)方法List<String> selectList(String text)方法,参数都是text,也就是json的字符串。

Demo

package us.codecraft.webmagic.selector;

import org.junit.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
* @author code4crafter@gmai.com <br>
*/
public class JsonPathSelectorTest {

private String text = "{ \"store\": {\n" +
"    \"book\": [ \n" +
"      { \"category\": \"reference\",\n" +
"        \"author\": \"Nigel Rees\",\n" +
"        \"title\": \"Sayings of the Century\",\n" +
"        \"price\": 8.95\n" +
"      },\n" +
"      { \"category\": \"fiction\",\n" +
"        \"author\": \"Evelyn Waugh\",\n" +
"        \"title\": \"Sword of Honour\",\n" +
"        \"price\": 12.99,\n" +
"        \"isbn\": \"0-553-21311-3\"\n" +
"      }\n" +
"    ],\n" +
"    \"bicycle\": {\n" +
"      \"color\": \"red\",\n" +
"      \"price\": 19.95\n" +
"    }\n" +
"  }\n" +
"}";

@Test
public void testJsonPath() {
System.out.println("需要解析的json:"+text);

JsonPathSelector jsonPathSelector = new JsonPathSelector("$.store.book[*].author");
String select = jsonPathSelector.select(text);
List<String> list = jsonPathSelector.selectList(text);

assertThat(select).isEqualTo("Nigel Rees");
assertThat(list).contains("Nigel Rees","Evelyn Waugh");

jsonPathSelector = new JsonPathSelector("$.store.book[?(@.category == 'reference')]");
list = jsonPathSelector.selectList(text);
select = jsonPathSelector.select(text);

System.out.println("select方法的结果:\t"+select);
System.out.println("selectList方法的结果:\t"+list);

assertThat(select).isEqualTo("{\"author\":\"Nigel Rees\",\"price\":8.95,\"category\":\"reference\",\"title\":\"Sayings of the Century\"}");
assertThat(list).contains("{\"author\":\"Nigel Rees\",\"price\":8.95,\"category\":\"reference\",\"title\":\"Sayings of the Century\"}");
}
}


个人见解

我觉得这个实现不太好。在一个page中,jsonStr是一样的,而提取规则不同。如果每次都new 一个新的JsonPathSelector作为提取规则,那要创建多少对象啊。而且和下面这种实现比较来说,提取规则开发方式不同:

String brand_price = html.xpath("//span[@id=\"item-sellprice\"]/text()").toString();
String brand_img = html.xpath("//img[@id=\"brand-img\"]/@src").toString();
String brand_describe = html.xpath("//p[@id=\"brand-describe\"]/text()").toString();
String location_text = html.xpath("//span[@id=\"location-text\"]/text()").toString();

估计不是我自己出现这种问题吧,所以就记录一下。嘿嘿。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  WebMagic