1. API(Application Programming Interface)
2. 웹에서는 어떻게 response하고 어떻게 request하는 지 매우 중요
3. XML 데이터 담는 용도로 사용
4. json(JavaScript Object Notation)
5. Node란? 데이터가 가지고 있는 것
: Type(Element, Attribute, Text, ... ), name, value
6. HTML 코드를 DOM으로 표현
** HTML 문서 **
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
</head>
<body>
<a href="http://www.naver.com">text</a>
<h1>My header</h1>
</body>
</html>
** DOM : https://www.w3schools.com/js/js_htmldom.asp **
7. 들여쓰기, 공백도 Text 노드로 인식
[그렇기 때문에...!!] 파싱하기전 꼭꼭 normalize()가 필요!! (필수 필수!!) * 100
[실습코드]
1. [과제] 크롤링을 이용하여 인터파크 도서 검색, 썸네일 이미지 다운로드
package com.lec.java.crawl07;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Scanner;
import javax.imageio.ImageIO;
import org.jsoup.Jsoup;
import org.jsoup.Connection.Response;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Crawl07Main {
// 썸네일 다운로드 추가
private static final String PATH = "books";
public static void main(String[] args) throws IOException {
System.out.println("인터파크 도서 검색결과 페이지");
Scanner sc = new Scanner(System.in);
System.out.print("검색어를 입력하세요 : ");
String search = sc.nextLine();
sc.close();
Crawl07Main app = new Crawl07Main();
ArrayList<InfoBook> list = app.crawlInterPark(search);
// 썸네일 이미지 다운로드 받기
int fileIndex = 1;
for(InfoBook e : list) {
System.out.println(e); // 크롤링 정보 출력
// 썸네일 이미지 다운로드
String fileName = String.format(PATH + File.separator + "thumb%03d.jpg", fileIndex);
URL imgUrl = new URL(e.getImgUrl());
BufferedImage imgData = ImageIO.read(imgUrl);
File file = new File(fileName);
ImageIO.write(imgData, "jpg", file);
System.out.println(fileName + " 이 저장되었습니다");
fileIndex++;
}
System.out.println("\n프로그램 종료");
} // end main()
private ArrayList<InfoBook> crawlInterPark(String search) throws IOException {
ArrayList<InfoBook> list = new ArrayList<InfoBook>();
String url;
Document doc;
Response response;
Element elements;
Elements rowElements;
// http://mbook.interpark.com/main/
url = "http://bsearch.interpark.com/dsearch/book.jsp?sch=all&sc.shopNo=&bookblockname=s_main&booklinkname=s_main&bid1=search_auto&bid2=product&bid3=000&bid4=001&query="
+ URLEncoder.encode(search, "euc-kr");
System.out.println(url);
doc = Jsoup.connect(url).execute().parse();
rowElements = doc.select("#bookresult > form").get(0).select("div.list_wrap");
System.out.println(rowElements.size() + " 개");
for(Element e : rowElements) {
String imgUrl = e.selectFirst("div.bookImg > div.imgWrap > div.bimgWrap > a > img").attr("src").trim();
//System.out.println(imgUrl); // 확인 끄읏~>ㅡ<
Element infoElement = e.selectFirst("div.info > p.tit > b > a");
String bookTitle = infoElement.text().trim();
String linkUrl = infoElement.attr("href").trim();
//System.out.println(bookTitle + " : " + linkUrl);
String price = e.selectFirst("p.FnowCoupon > span.nowMoney").text().replace(",", "").split("원")[0].trim();
//System.out.println(price + "!!");
double prices = Double.parseDouble(e.selectFirst("p.FnowCoupon > span.nowMoney").text().replace(",", "").split("원")[0].trim());
//System.out.println(price + "원");
list.add(new InfoBook(bookTitle, prices, linkUrl, imgUrl));
}
return list;
}
} // end class
package com.lec.java.crawl07;
public class InfoBook {
private String bookTitle; // 책제목
private double price; // 책가격
private String url; // 상세페이지 url
private String imgUrl; // 썸네일 url
// 기본생성자
public InfoBook() {}
// 매개변수 생성자
public InfoBook(String bookTitle, double price, String url, String imgUrl) {
super();
this.bookTitle = bookTitle;
this.price = price;
this.url = url;
this.imgUrl = imgUrl;
}
// getter&setter
public String getBookTitle() {return bookTitle;}
public void setBookTitle(String bookTitle) {this.bookTitle = bookTitle;}
public double getPrice() {return price;}
public void setPrice(double price) {this.price = price;}
public String getUrl() {return url;}
public void setUrl(String url) {this.url = url;}
public String getImgUrl() {return imgUrl;}
public void setImgUrl(String imgUrl) {this.imgUrl = imgUrl;}
@Override
public String toString() {
return bookTitle + ":" + price + "원, URL: " + url + ", img: " + imgUrl;
}
}
2. Lec32_WebCrawl
1) com.lec.java.crawl08 패키지, Crawl08Main 클래스
package com.lec.java.crawl08;
import java.io.IOException;
import java.net.URLEncoder;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
/*
* 크롤링 검색 페이징
* - '첫 페이지' url
* - '두번째 페이지'부터의 url 변화 확인 : 어떤 방식? 어떤 parameter 사용?
* - 검색결과 페이징의 '마지막 페이지'는 어떻게 처리하는지 확인
*/
public class Crawl08Main {
public static void main(String[] args) throws IOException {
System.out.println("페이징 : Pagination");
for(int i = 1; i <= 10; i ++) {
crawlDaumBlog("파이썬", i);
}
System.out.println("\n프로그램 종료");
} // end main()
/**
*
* @param search 검색어
* @param page 검색할 결과 page 번호
*/
public static void crawlDaumBlog(String search, int page) throws IOException {
// 목록에서 크롤링 할 내용
// post title
// post link url
// blog title
// 매개변수 검증
if(search == null || search.trim().length() == 0 || page < 1) {return;}
String url;
Document doc;
Elements elements;
System.out.println(page + " 페이지]");
url = String.format("https://search.daum.net/search?w=blog&DA=PGD&enc=utf8&q=%s&page=%d",
URLEncoder.encode(search, "utf-8"), page);
//System.out.println(url); // 확인용
doc = Jsoup.connect(url).execute().parse();
elements = doc.select("#blogColl .list_info li .wrap_cont");
//System.out.println(elements.size() + " 개"); // 확인용
for(Element e : elements) {
String postTitle = e.selectFirst("a").text().trim();
String blogTitle = e.selectFirst(".info .f_nb").text().trim();
String postUrl = e.selectFirst("a").attr("href").trim();
System.out.println(postTitle + " : " + blogTitle + " : " + postUrl);
} // end for
System.out.println();
} // end crawlDaumBlog()
} // end class
2) com.lec.java.crawl09 패키지, Crawl09Main 클래스
package com.lec.java.crawl09;
import java.io.IOException;
import java.net.URLEncoder;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
// 연습
// 네이버 '검색어'
// -post title
// -post url
// -blog title
// 페이징 구현
public class Crawl09Main {
public static void main(String[] args) throws IOException {
System.out.println("네이버 검색, 페이징");
for(int i = 1; i <= 10; i++) {
crawlNaverBlog("파이썬", i);
}
System.out.println("\n프로그램 종료");
} // end main()
public static void crawlNaverBlog(String search, int page) throws IOException {
// 매개변수 검증
if(search == null || search.trim().length() == 0 || page < 1) {return;}
String url;
Document doc;
Elements elements;
System.out.println(page + "페이지]");
url = String.format("https://search.naver.com/search.naver?date_from=&date_option=0&date_to=&dup_remove=1&nso=&post_blogurl=&post_blogurl_without=&query=%s&sm=tab_pge&srchby=all&st=sim&where=post&start=%d",
URLEncoder.encode(search, "utf-8"), (page-1) * 10 + 1);
//System.out.println(url); // 확인용
doc = Jsoup.connect(url).execute().parse();
elements = doc.select("#elThumbnailResultArea > li.sh_blog_top > dl");
//System.out.println(elements.size()); // 확인용
for(Element e : elements) {
String postTitle = e.selectFirst("a.sh_blog_title").text().trim();
String blogTitle = e.selectFirst("dd.txt_block a.txt84").text().trim();
String postUrl = e.selectFirst("a.sh_blog_title").attr("href").trim();
System.out.println(postTitle + " : " + blogTitle + " : " + postUrl);
} // end for
System.out.println();
} // end crawlNaverBlog()
} // end class
3) com.lec.java.crawl10 패키지, Crawl10Main 클래스
package com.lec.java.crawl10;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/*
* XML, Json 파싱1
*
* ■서울시 지하철호선별 역별 승하차 인원 정보
* http://data.seoul.go.kr/dataList/datasetView.do?infId=OA-12914&srvType=A&serviceKind=1¤tPageNo=1
*
* 샘플 url
* XML 버젼
* http://openapi.seoul.go.kr:8088/키값을넣으세요/xml/CardSubwayStatsNew/1/5/20181001
* 예) http://openapi.seoul.go.kr:8088/704c4a6d7262696e33396a544e7551/xml/CardSubwayStatsNew/1/5/20181001
*
* JSON 버젼
* http://openapi.seoul.go.kr:8088/키값을넣으세요/json/CardSubwayStatsNew/1/5/20181001
* 예) http://openapi.seoul.go.kr:8088/704c4a6d7262696e33396a544e7551/json/CardSubwayStatsNew/1/5/20181001
* */
/*
* JSON 파싱
* java.io.Reader 프로그램이 '문자 단위' 데이터를 읽어들이는(read) 통로
* ├─ java.io.InputStreamReader // 스트림 기반의 reader
* └─ java.io.BufferedReader // 문자(character) 기반 reader
*/
public class Crawl10Main {
public static final String REQ_SERVICE = "CardSubwayStatsNew";
public static final String API_KEY = "704c4a6d7262696e33396a544e7551";
public static void main(String[] args) {
System.out.println("서울시 지하철호선별 역별 승하차 인원 정보");
int startIndex; // 요청 시작 위치 정수 입력 (페이징 시작번호입니다 : 데이터행 시작번호)
int endIndex; // 요청 종료 위치 정수 입력 (페이징 끝번호 입니다 : 데이터 행 끝번호)
String date; // 날짜 yyyymmdd 형식
String url_address;
StringBuffer sb; // response 받은 텍스트
startIndex = 1;
endIndex = 5;
date = "20200329";
System.out.println("--- XML 파싱 ---");
url_address = buildUrlAddress("xml", startIndex, endIndex, date);
//System.out.println(url_address); // URL 확인
sb = readFromUrl(url_address);
parseXML(sb.toString());
System.out.println();
System.out.println("--- JSON 파싱 ---");
url_address = buildUrlAddress("json", startIndex, endIndex, date);
//System.out.println(url_address); // URL 확인
sb = readFromUrl(url_address);
parseJSON(sb.toString());
System.out.println("\n프로그램 종료");
} // end main()
public static String buildUrlAddress(String reqType, int startIndex, int endIndex, String date) {
String url_address = String.format("http://openapi.seoul.go.kr:8088/%s/%s/CardSubwayStatsNew/%d/%d/%s", API_KEY, reqType, startIndex, endIndex, date);
return url_address;
} // end buildUrlAddress()
/**
*
* @param urlAddress : 주어진 url 주소
* @return 서버로부터 받은 텍스트데이터(HTML) 리턴
*/
public static StringBuffer readFromUrl(String urlAddress) {
StringBuffer sb = new StringBuffer(); // response 받은 데이터 담을 객체
URL url = null; // java.net.URL
HttpURLConnection conn = null; // java.net.HttpURLConnectrion
InputStream in = null;
InputStreamReader reader = null; // byte 스트림 --> 문자기반 Reader
BufferedReader br = null;
char[] buf = new char[512]; // 문자용 버퍼
// BufferedReader <- InputStreamReader <- InputStream <- HttpURLConnection
try {
url = new URL(urlAddress);
conn = (HttpURLConnection)url.openConnection(); // Connection 객체 생성
if(conn != null) {
conn.setConnectTimeout(2000); // 2초이내에 '연결'이 수립안되면
// java.net.SocketTimeoutException 발생
conn.setRequestMethod("GET"); // GET 방식 request
// "GET", "POST", ...
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
conn.setUseCaches(false); // 캐시사용안함
System.out.println("request 시작: " + urlAddress);
conn.connect(); // request 발생 --> 이후 response 받을때까지 delay
System.out.println("response 완료");
// response 받은 후 가장 먼저 response code 값 확인
int restponseCode = conn.getResponseCode();
System.out.println("response code: " + restponseCode);
// 참조 : https://developer.mozilla.org/ko/docs/Web/HTTP/Status
if(restponseCode == HttpURLConnection.HTTP_OK) {
in = conn.getInputStream(); // InputStream <- HttpURLConnection
reader = new InputStreamReader(in, "utf-8");// InputStreamReader<-InputStream
br = new BufferedReader(reader); // BufferedReader <- InputStreamReader
int cnt; // 읽은 글자 개수
while((cnt = br.read(buf)) != -1) {
sb.append(buf, 0, cnt); // response 받은 텍스트를 StringBuffer에 추가
}
} else {
System.out.println("response 실패");
return null;
}
} else {
System.out.println("conn null");
return null;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if(conn != null) {conn.disconnect();} // 작업 끝나고 Connection 해제
}
return sb;
} // end readFromUrl()
public static void parseXML(String xmlText) {
// XML 파싱
DocumentBuilderFactory dbFactory;
DocumentBuilder dBuilder;
try {
// DOM parser 객체 생성
dbFactory = DocumentBuilderFactory.newInstance();
dBuilder = dbFactory.newDocumentBuilder();
// String -> InputStream 변환
InputStream in = new ByteArrayInputStream(xmlText.getBytes("utf-8"));
// InputStream -> DOM 객체 생성
Document dom = dBuilder.parse(in);
// DOM 최상위 document element 추출
Element docElement = dom.getDocumentElement(); // DOM 의 최상위 element
// 파싱하기전 normalize()
docElement.normalize(); // 흩어진 text node 들을 정렬하는 등의 절차
// XML 파싱하기 전에 꼭 normalize() 부터 해주자
// DOM 내의 데이터 파싱.
// <row> ... </row> element 들로 구성된 NodeList 리턴
NodeList nList = docElement.getElementsByTagName("row");
System.out.println("<row> 개수 : " + nList.getLength());
System.out.println();
for (int i = 0; i < nList.getLength(); i++) {
Node node = nList.item(i);
//System.out.println("node type : " + node.getNodeType()); // node type 확인용
// element node 인 경우만 파싱 진행
if(node.getNodeType() != Node.ELEMENT_NODE) {continue;}
// 오른쪽이 부모일 때, 형변환이 필요...!!
Element rowElement = (Element)node;
String LINE_NUM =
rowElement.getElementsByTagName("LINE_NUM").item(0).getChildNodes().item(0).getNodeValue().trim();
String SUB_STA_NM =
rowElement.getElementsByTagName("SUB_STA_NM").item(0).getChildNodes().item(0).getNodeValue().trim();
String RIDE_PASGR_NUM =
rowElement.getElementsByTagName("RIDE_PASGR_NUM").item(0).getChildNodes().item(0).getNodeValue().trim();
String ALIGHT_PASGR_NUM =
rowElement.getElementsByTagName("ALIGHT_PASGR_NUM").item(0).getChildNodes().item(0).getNodeValue().trim();
System.out.printf("%5s : %8s역 [승차:%6s 하차:%6s]\n",
LINE_NUM, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} // end parseXML()
public static void parseJSON(String jsonText) {
// org.json 라이브러리 다운로드
// https://mvnrepository.com/artifact/org.json/json
// 최신버젼 클릭후, Files 항목 클릭해서 다운로드
JSONObject jObj = new JSONObject(jsonText); // JSON파싱 : JSONObject <- String
JSONArray row = jObj.getJSONObject("CardSubwayStatsNew").getJSONArray("row");
System.out.println("<row> 개수: " + row.length());
System.out.println();
for(int i = 0; i < row.length(); i++) {
JSONObject station = row.getJSONObject(i);
String LINE_NUM = station.getString("LINE_NUM");
String SUB_STA_NM = station.getString("SUB_STA_NM");
int RIDE_PASGR_NUM = station.getInt("RIDE_PASGR_NUM");
int ALIGHT_PASGR_NUM = station.getInt("ALIGHT_PASGR_NUM");
System.out.printf("%5s : %8s역 [승차:%6s 하차:%6s]\n",
LINE_NUM, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM);
} // end for
} // end parseJSON()
} // end class
4) com.lec.java.crawl11 패키지, Crawl11Main 클래스
package com.lec.java.crawl11;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/*
* XML, JSON 파싱 연습
* ■서울시 지하철 역사 정보
* http://data.seoul.go.kr/dataList/datasetView.do?infId=OA-12753&srvType=A&serviceKind=1¤tPageNo=1
*
* 샘플url
*
* XML 버젼
* http://swopenAPI.seoul.go.kr/api/subway/704c4a6d7262696e33396a544e7551/xml/stationInfo/1/5/서울
*
* JSON 버젼
* http://swopenAPI.seoul.go.kr/api/subway/704c4a6d7262696e33396a544e7551/json/stationInfo/1/5/서울
*
*/
public class Crawl11Main {
public static final String REQ_SERVICE = "stationInfo";
public static final String API_KEY = "704c4a6d7262696e33396a544e7551"; // 내 인증키
public static void main(String[] args) throws IOException {
System.out.println("서울시 지하철 역사(station) 정보");
int startIndex; // 요청 시작 위치 정수 입력 (페이징 시작번호입니다 : 데이터행 시작번호)
int endIndex; // 요청 종료 위치 정수 입력 (페이징 끝번호 입니다 : 데이터 행 끝번호)
String place; // 날짜 yyyymmdd 형식
String url_address;
StringBuffer sb; // response 받은 텍스트
startIndex = 1;
endIndex = 5;
place = "서울";
System.out.println("--- XML 파싱 ---");
url_address = buildUrlAddress("xml", startIndex, endIndex, place);
//System.out.println(url_address); // 확인용
sb = readFromUrl(url_address);
parseXML(sb.toString());
System.out.println();
System.out.println();
System.out.println("--- JSON 파싱 ---");
url_address = buildUrlAddress("json", startIndex, endIndex, place);
//System.out.println(url_address);
sb = readFromUrl(url_address);
parseJSON(sb.toString());
System.out.println("\n프로그램 종료");
} // end main()
public static String buildUrlAddress(String reqType, int startIndex, int endIndex, String place) throws IOException {
String url_address = (String.format("http://swopenapi.seoul.go.kr/api/subway/%s/%s/%s/%d/%d/",
API_KEY, reqType, REQ_SERVICE, startIndex, endIndex))
+ URLEncoder.encode(place, "utf-8");
return url_address;
}
/**
*
* @param urlAddress : 주어진 url 주소
* @return 서버로부터 받은 텍스트데이터(HTML) 리턴
*/
public static StringBuffer readFromUrl(String urlAddress) {
StringBuffer sb = new StringBuffer(); // response 받은 데이터 담을 객체
URL url = null; // java.net.URL
HttpURLConnection conn = null; // java.net.HttpURLConnectrion
InputStream in = null;
InputStreamReader reader = null; // byte 스트림 --> 문자기반 Reader
BufferedReader br = null;
char[] buf = new char[512]; // 문자용 버퍼
// BufferedReader <- InputStreamReader <- InputStream <- HttpURLConnection
try {
url = new URL(urlAddress);
conn = (HttpURLConnection)url.openConnection(); // Connection 객체 생성
if(conn != null) {
conn.setConnectTimeout(2000); // 2초이내에 '연결'이 수립안되면
// java.net.SocketTimeoutException 발생
conn.setRequestMethod("GET"); // GET 방식 request
// "GET", "POST", ...
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
conn.setUseCaches(false); // 캐시사용안함
System.out.println("request 시작: " + urlAddress);
conn.connect(); // request 발생 --> 이후 response 받을때까지 delay
System.out.println("response 완료");
// response 받은 후 가장 먼저 response code 값 확인
int restponseCode = conn.getResponseCode();
System.out.println("response code: " + restponseCode);
// 참조 : https://developer.mozilla.org/ko/docs/Web/HTTP/Status
if(restponseCode == HttpURLConnection.HTTP_OK) {
in = conn.getInputStream(); // InputStream <- HttpURLConnection
reader = new InputStreamReader(in, "utf-8");// InputStreamReader<-InputStream
br = new BufferedReader(reader); // BufferedReader <- InputStreamReader
int cnt; // 읽은 글자 개수
while((cnt = br.read(buf)) != -1) {
sb.append(buf, 0, cnt); // response 받은 텍스트를 StringBuffer에 추가
}
} else {
System.out.println("response 실패");
return null;
}
} else {
System.out.println("conn null");
return null;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
if(conn != null) {conn.disconnect();} // 작업 끝나고 Connection 해제
}
return sb;
}
public static void parseXML(String xmlText) {
// XML 파싱
DocumentBuilderFactory dbFactory;
DocumentBuilder dBuiler;
try {
// DOM parser 객체 생성
dbFactory = DocumentBuilderFactory.newInstance();
dBuiler = dbFactory.newDocumentBuilder();
// String -> InputStream 변환
InputStream in = new ByteArrayInputStream(xmlText.getBytes("utf-8"));
// InputStream -> DOM 객체 생성
Document dom = dBuiler.parse(in);
// DOM 최상위 document element 추출
Element docElement = dom.getDocumentElement(); // DOM 의 최상위 element
// 파싱하기전 꼭꼭 normalize()!!!
docElement.normalize(); // 흩어진 text node 들을 정렬하는 등의 절차
// DOM 내의 데이터 파싱.
// <row> ... </row> element 들로 구성된 NodeList 리턴
NodeList nList = docElement.getElementsByTagName("row");
System.out.println("<row> 개수 : " + nList.getLength());
//statnNm subwayId subwayNm
//역이름 호선 id 이름
System.out.println();
for (int i = 0; i < nList.getLength(); i++) {
Node node = nList.item(i);
//System.out.println("node type : " + node.getNodeType());
// element node 인 경우만 파싱 진행
if(node.getNodeType() != Node.ELEMENT_NODE) {continue;}
// 오른쪽이 부모일 때, 형변환이 필요...!!
Element rowElement = (Element)node;
String statnNm =
rowElement.getElementsByTagName("statnNm").item(0).getChildNodes().item(0).getNodeValue().trim();
String subwayId =
rowElement.getElementsByTagName("subwayId").item(0).getChildNodes().item(0).getNodeValue().trim();
String subwayNm =
rowElement.getElementsByTagName("subwayNm").item(0).getChildNodes().item(0).getNodeValue().trim();
System.out.println((i + 1) + " "+ statnNm + "역 " + subwayId + " " + subwayNm);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // end parseXML()
public static void parseJSON(String jsonText) {
JSONObject jObj = new JSONObject(jsonText); // JSON 파싱 <- String
JSONArray row = jObj.getJSONArray("stationList");
System.out.println("<row> 의 개수 : " + row.length());
System.out.println();
for(int i = 0; i < row.length(); i++) {
JSONObject station = row.getJSONObject(i);
String statnNm = station.getString("statnNm");
String subwayId = station.getString("subwayId");
String subwayNm = station.getString("subwayNm");
System.out.println((i + 1) + " "+ statnNm + "역 " + subwayId + " " + subwayNm);
} // end for
} // end parseJSON()
} // end class
5) com.lec.java.crawl12 패키지, Crawl12Main 클래스
package com.lec.java.crawl12;
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
/*
* Jsoup 를 사용한 XML 파싱
*/
public class Crawl12Main {
public static final String REQ_SERVICE = "CardSubwayStatsNew";
public static final String API_KEY = "704c4a6d7262696e33396a544e7551";
public static void main(String[] args) throws IOException {
System.out.println("서울시 지하철호선별 역별 승하차 인원 정보");
String url = buildUrlAddress("xml", 1, 5, "2020.03.29");
// XML 파싱할 때는 xml parser를 사용한다.
Document doc = Jsoup.connect(url).parser(Parser.xmlParser()).get();
Elements elements = doc.select("row");
for(Element e : elements) {
String LINE_NUM =
e.selectFirst("LINE_NUM").text().trim();
String SUB_STA_NM =
e.select("SUB_STA_NM").text().trim();
String RIDE_PASGR_NUM =
e.select("RIDE_PASGR_NUM").text().trim();
String ALIGHT_PASGR_NUM =
e.select("ALIGHT_PASGR_NUM").text().trim();
System.out.printf("%5s : %8s역 [승차:%6s 하차:%6s]\n",
LINE_NUM, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM);
}
} // end main()
public static String buildUrlAddress(String reqType, int startIndex, int endIndex, String date) {
String url_address = String.format("http://openapi.seoul.go.kr:8088/%s/%s/CardSubwayStatsNew/%d/%d/%s", API_KEY, reqType, startIndex, endIndex, date);
return url_address;
} // end buildUrlAddress()
} // end class
'웹_프론트_백엔드 > JAVA프레임윅기반_풀스택' 카테고리의 다른 글
2020.04.06 (0) | 2020.04.06 |
---|---|
2020.04.03 (0) | 2020.04.03 |
2020.04.01 (0) | 2020.04.01 |
2020.03.31 (0) | 2020.03.31 |
2020.03.30 (0) | 2020.03.30 |