2017-03-01 20 views
0

Shodanのクエリ結果を解析し、設定した基準に一致する結果だけを含む新しいJSONファイルを作成しようとしています。Shodanのクエリ結果を場所に基づいてフィルタリングする

例JSONエントリ:

{ 
    "matches": [ 
    { 
     "product": "Microsoft IIS httpd", 
     "hostnames": [], 
     "hash": -1722221328, 
     "ip": 1261462342, 
     "isp": "AT&T Internet Services", 
     "transport": "tcp", 
     "cpe": [ 
     "cpe:/a:microsoft:iis:7.5", 
     "cpe:/o:microsoft:windows" 
     ], 
     "data": "", 
     "asn": "AS7018", 
     "port": 631, 
     "version": "7.5", 
     "link": "Ethernet or modem", 
     "location": { 
     "city": null, 
     "region_code": null, 
     "area_code": null, 
     "longitude": -97.822, 
     "country_code3": "USA", 
     "latitude": 37.751000000000005, 
     "postal_code": null, 
     "dma_code": null, 
     "country_code": "US", 
     "country_name": "United States" 
     }, 
     "timestamp": "2017-02-28T23:55:24.306344", 
     "domains": [], 
     "org": "AT&T Internet Services", 
     "os": null, 
     "_shodan": { 
     "crawler": "122dd688b363c3b45b0e7582622da1e725444808", 
     "id": null, 
     "module": "http-simple-new", 
     "options": {} 
     }, 
     "ip_str": "75.48.99.70" 
    }, 
    { 
     "hash": 605323305, 
     "ip": 1757819678, 
     "isp": "Google Cloud", 
     "transport": "tcp", 
     "data": "", 
     "asn": "AS15169", 
     "port": 9000, 
     "hostnames": [ 
     "30.51.198.104.bc.googleusercontent.com" 
     ], 
     "location": { 
     "city": "Mountain View", 
     "region_code": "CA", 
     "area_code": 650, 
     "longitude": -122.0574, 
     "country_code3": "USA", 
     "latitude": 37.41919999999999, 
     "postal_code": "94043", 
     "dma_code": 807, 
     "country_code": "US", 
     "country_name": "United States" 
     }, 
     "timestamp": "2017-02-28T23:51:35.997036", 
     "domains": [ 
     "googleusercontent.com" 
     ], 
     "org": "Google Cloud", 
     "os": null, 
     "_shodan": { 
     "crawler": "545144fc95e7a7ef13ece5dbceb98ee386b37950", 
     "id": null, 
     "module": "https-simple-new", 
     "options": {} 
     }, 
     "ip_str": "104.198.51.30" 
    } 
    ], 
    "total": 2 
} 

私の希望は、それが「US」の位置COUNTRY_CODEを持つの基準に一致しない場合、JSONファイルをロードし、要素のセットを反復処理、要素を削除することです。次のように

私が持っているコード(https://gist.github.com/madonnellyIterate over JsonObject propertiesの礼儀)は次のとおりです。

import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.util.Map; 
import java.util.Set; 

import com.google.gson.JsonArray; 
import com.google.gson.JsonElement; 
import com.google.gson.JsonObject; 
import com.google.gson.JsonParser; 

public class ParseJSON { 

    public static void main(String[] args) { 
     JsonObject shodanJSON = convertFileToJSON("<Path to JSON file>"); 

     Set<Map.Entry<String,JsonElement>> queryResults = shodanJSON.entrySet(); 

     for (Map.Entry<String, JsonElement> queryResult : queryResults) { 
      JsonArray locArray = queryResult.getValue().getAsJsonObject().getAsJsonArray("location"); 
      for (JsonElement locData : locArray) { 
       if (locData.getAsJsonObject().getAsJsonPrimitive("country_code").equals("US")) { 
        System.out.println(locData.getAsString()); 
       } 
      } 
     } 
    } 

    public static JsonObject convertFileToJSON(String fileName) { 

     // Read from File to String 
     JsonObject jsonObject = new JsonObject(); 

     try { 
      JsonParser parser = new JsonParser(); 
      JsonElement jsonElement = parser.parse(new FileReader(fileName)); 
      jsonObject = jsonElement.getAsJsonObject(); 
     } catch (FileNotFoundException e) { 

     } 
     return jsonObject; 
    } 
} 

私は私のコードを実行すると、私はスレッド「メイン」のjavaでエラー

例外を受け付けております。 lang.IllegalStateException:JSONでない オブジェクト:[{"product": "Microsoft IIS httpd"、 "hostnames":[]、 "hash": - 1722221328、 "ip":1261462342、 "isp": "AT & T インターネットサービス "、"トランスポート ":...}] com.cti.shodan.ParseJSON.main(ParseJSON.java:22)

で com.google.gson.JsonElement.getAsJsonObject(JsonElement.java:90)で私はトンを作っています確信しています私が作っている間違いを誰かが指摘できると思っています。前もって感謝します!

+0

をあなたが読んでみてくださいましたGson javadoc? [ここにリンクがあります](http://www.javadoc.io/doc/com.google.code.gson/gson/2.8.0)。 'JsonElement'クラスのドキュメントを見て、' getAsJsonObject() 'を見てください。それは例外が何を意味するのかを教えてくれます。 – ajb

+0

javadocは多少役立ちます。 JSONファイルが一連のマッチであることに気づき、それに応じて処理する必要があります。 修正されたコード: ( 'のMap.Entry <文字列、JsonElement> QueryResultでは:queryResults)のために。{ \t \t \t JsonArrayが一致= queryResult.getValue()getAsJsonArray(); (JsonElementマッチ:試合)のための\t \t \t \t \t \t {; ' が、私は、私は位置データにアクセスする方法として、今失われています。 – cbarreras

答えて

1

実際の構造を満たしていない具体的なJSONドキュメント解析について、いくつかの前提があります。私はあなたのサブプロパティ値($.matches.*.location.country_code)を除外して一致する結果($.matches)を表示すると仮定しています。 Javaの8で

for (final Entry<String, JsonElement> queryResult : shodanJsonObject.entrySet()) { 
     final JsonElement value = queryResult.getValue(); 
     // This is necessary to skip <"total": 2> 
     if (value.isJsonArray()) { 
      // Here comes an array, and should be iterated, rather than taken as an object 
      for (final JsonElement match : value.getAsJsonArray()) { 
       // This was the root cause, not an array 
       final JsonObject location = match.getAsJsonObject().getAsJsonObject("location"); 
       // Previously jsonPrimitive.equals("US") -- convert the JSON primitive to a string first 
       if (location.getAsJsonPrimitive("country_code").getAsString().equals("US")) { 
        // Previously getAsString() -- it requires a JSON string literal, just remove it 
        System.out.println(match); 
       } 
      } 
     } 
    } 

それはもう少し簡単なことがあります

shodanJsonObject.entrySet() 
     .stream() 
     .map(Entry::getValue) 
     .filter(JsonElement::isJsonArray) 
     .map(JsonElement::getAsJsonArray) 
     .flatMap(jsonElements -> StreamSupport.stream(jsonElements.spliterator(), false)) 
     .peek(System.out::println) 
     .map(JsonElement::getAsJsonObject) 
     .map(jsonObject -> jsonObject.getAsJsonObject("location")) 
     .filter(location -> location.getAsJsonPrimitive("country_code").getAsString().equals("US")) 
     .forEach(jsonObject -> { 
     }); // forEach is a terminal operation and it "pushes" the entire chain above 

そしておそらく最も表現方法、それはJsonPathのようなライブラリの照会に使用することが可能です場合:

final JsonPath jsonPath = JsonPath.compile("$.matches.*[?(@.location.country_code=='US')]"); 
for (final Object match : jsonPath.<JSONArray>read(JSON)) { 
    System.out.println(match); 
} 
+0

最初のオプションは私にとって素晴らしい作品です。あなたの専門知識を共有してくれてありがとう! null値を扱うためにcountry_codeをチェックするときに '!location.get(" country_code ")。isJsonNull()'を追加しました。 – cbarreras

+0

@cbarreras問題はない、私はあなたを助けることができてうれしい。 :) –

関連する問題