열심히 끝까지
2Quals - EmartMall 크롤링 및 제작 feat.2Quals팀 본문
- 이마트 웹페이지에 대한 분석
>> 크롤링하는 방법은 생각보다 어려웠습니다.
1. 이마트의 제품 이름
제품 이름을 출력하기 위해 개발자도구를 이용해 제품이름을 주는 지정자를 찾았습니다.
하지만 긁어와서 출력했을 때는 제가 원하는 제품이름을 제외한 이름,
"이마트몰", "E-MART FRESH", "No Brand"와 같은 이름들도 출력되기 시작했습니다.
이 문제를 해결하기 위해 제가 원하는 값을 가지는 지정자의 위를 거슬러 올라가
그 값이 지니는 li.class의 이름을 가져와 출력했습니다.
그러자 제가 원하는 제품 이름 값을 가져올 수 있게 되었습니다.
2. 이마트의 가격
가격도 제품과 마찬가지였습니다.
현재 팔고 있는 가격 포함 할인되기 전 가격도 출력하는 바람에 수박의 가격이 다음과 같이 저장되는 일이 있었습니다
정말 금수박이 되어버린 상황이 발생해, 열심히 찾았습니다.
가격도 제품 이름과 마찬가지로 지정자를 따라 올라가 li.class을 지정해주니 현재 판매가만 출력했습니다.
거기에 추가적으로 금액을 String으로 받아오는 것은 가능했지만 나중에 update로 금액을 바꿔주고 싶었을 때,
String으로 넣어야 하는 불편함이 있었습니다.
그래서 크롤링 할 때, String값을 int값으로 바꾸는 parseInt식을 사용하여 ,를 없애고 숫자만을 남겨
가격란에 담았습니다.
3. 이마트의 리뷰 수
이마트의 리뷰 수는 이마트의 가격과 별 다를 바가 없었습니다.
리뷰수도 똑같이 숫자를 제외한 , 이런 것을 제거하고 String 값을 parseInt식을 사용하여 int값으로 변환시켜
리뷰 수에 담아두었습니다.
4. 이마트의 구분(카테고리)
이마트의 카테고리를 구분해서 담아오는 것에서 고민을 많이 했었습니다.
BEST 상품을 담아오면 구분없이 담아와 저희는 구분을 해주기 위해
5개의 품목에서 각 20개씩 받아올 생각을 했었습니다.
카테고리는 테이블에 join을 통해 한글을 받아올 생각으로 크롤링할 때는 숫자로 지정했습니다.
각 파트마다 101부터 시작하여 다음 카테고리를 201 식으로 늘어나도록 지정한 채로 받았습니다.
한 페이지에서 한꺼번에 100개씩 담아오는 건 막히지 않았지만
카테고리마다 다른 주소를 쓰는 관계로 각 주소에서 20개씩 받아온 그 과정에서
크롤링이 막히는 사건이 발생했습니다.
주소를 옮겨가며 빠르게 자주 크롤링을 하니 발생하는 문제였습니다.
그래서 저희가 쓴 방법은 한 카테고리를 받고나서 딜레이를 주고 딜레이 후에 다시 받아오도록 했습니다.
그러자 크롤링은 다행이 잘 진행이 되었고 테이블에도 잘 담기는 것이 확인되었습니다.
5. 이마트의 이미지
이마트의 이미지를 가져오는 것도 큰 고난이였습니다.
저희는 이마트의 이미지의 주소를 저장해 띄우는 방식을 진행했었습니다.
주소를 담아오는 건 좋은데 그 담은 주소의 이미지를 어떻게 띄우는 지가 관건이였습니다.
저희가 그 해결을 배우지 않아서 고민하고 여러 구글링을 통해 한 분의 이미지 가져오는 로직을
그대로 가져오게 되었습니다.(view.Program)
뭔가.. 많이 쓰여있었지만 약간의 이해를 할 수 있는 것들이 있었습니다.
다음에 기회가 되면 완전히 이해하는 시간을 갖고 싶습니다.
>> Emart 크롤링 하기위해 사용한 주소(한 개) 및 크롤링 방법 기술
String str1= = "https://emart.ssg.com/category/main.ssg?dispCtgId=6000095739" // (과일)
view.Crawling(str1,101); // (뷰 파트에 저장 해 놓은 insert방법 가져오기)
public void Crawling(String http,int i2) { // url과 카테고리 번호 입력
final String url=http;
Document doc=null;
try {
doc=Jsoup.connect(url).get();
} catch (IOException e) {
e.printStackTrace();
}
Elements eles=doc.select("ul>li.cunit_t232>div>div>div>a>em.tx_ko"); // 이름
Elements eles2=doc.select("ul>li.cunit_t232>div>div>div>em.ssg_price"); // 금액
Elements eles3=doc.select("ul>li.cunit_t232>div>div>div>span>em"); // 리뷰수
Elements eles4=doc.select("ul>li.cunit_t232>div>div.thmb>a>img.i1"); // 이미지
Iterator<Element> itr=eles.iterator(); //이름
Iterator<Element> itr2=eles2.iterator(); //금액
Iterator<Element> itr3=eles3.iterator(); //리뷰수
Iterator<Element> itr4=eles4.iterator(); //이미지
for(int i=0;i<20;i++) {
String str=itr.next().text();
String str2=itr2.next().text();
String str3=itr3.next().text();
String str4=itr4.next().attr("src");
EmartMallVO vo=new EmartMallVO();
System.out.println(str);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
vo.seteName(str); //이름
vo.setePrice(Integer.parseInt(str2.replaceAll("[^0-9]", ""))); //금액
vo.seteReview(Integer.parseInt(str3.replaceAll("[^0-9]", ""))); //리뷰수
vo.seteImg(str4); // 이미지
this.inputDB(vo,i2); // insert에 vo 입력
}
// System.out.println("로그: DB에 저장완료!");
}
>> Emart 간단 userflow
>> Emart의 모든 로직(JDBCUtill는 제외)
>> 깃허브에서도 확인 가능 > 조금 더 고친 코드
> https://github.com/Rhoyoorim/EmartCrawling.git
----------------------------PersonVO
package model;
public class PersonVO {
private int sid;
private String name;
private String uid;
private String upw;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUpw() {
return upw;
}
public void setUpw(String upw) {
this.upw = upw;
}
}
----------------------------PersonDAO
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class PersonDAO {
final String sql_idcheck = "SELECT MID FROM USERDATA";
final String sql_insert = "INSERT INTO USERDATA VALUES((SELECT NVL(MAX(SID),0)+1 FROM USERDATA),?,?,?)";
final String sql_update = "UPDATE USERDATA SET MPW = ? WHERE SID = ?";
final String sql_delete = "DELETE FROM USERDATA WHERE SID = ?";
final String sql_check = "SELECT COUNT(*) FROM USERDATA";
final String sql_logincheck = "SELECT * FROM USERDATA WHERE MID = ?";
final String sql_loginCurret = "SELECT * FROM USERDATA WHERE MID = ?";
final String sql_buylist ="SELECT E.* FROM EPRODUCT E,BUYLIST B where B.EID = E.EID AND B.SID = ?";
Connection conn = null;
PreparedStatement stmt = null;
public ArrayList<EmartMallVO> buylist_user(PersonVO vo) {
conn = JDBCUtill.connect();
ArrayList<EmartMallVO> data = new ArrayList<EmartMallVO>();
try {
stmt = conn.prepareStatement(sql_buylist);
stmt.setInt(1, vo.getSid());
ResultSet rs = stmt.executeQuery();
// System.out.println(vo.getSid());
while(rs.next()) {
//일단 다담아보았습니다 알아서 꺼내쓰세여
//지우셔도 됩니다~ :D
// CREATE TABLE BUYLIST(
// PID INT PRIMARY KEY,
// EID INT,
// SID INT
// );
EmartMallVO evo2 = new EmartMallVO();
evo2.seteId(rs.getInt("EID"));
evo2.seteName(rs.getString("ENAME"));
evo2.setePrice(rs.getInt("EPRICE"));
evo2.seteImg(rs.getString("EIMG"));
// System.out.println(evo2.geteId());
data.add(evo2);
// System.out.println("로그1");
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
return data;
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
public boolean idcheck_user(PersonVO vo) {
//아이디 중복 체크
//중복이면 참 아니면 거짓
conn = JDBCUtill.connect();
try {
stmt = conn.prepareStatement(sql_idcheck);
// stmt.executeUpdate();
ResultSet rs = stmt.executeQuery();
stmt.executeQuery();
while(rs.next()) {
if(rs.getString("MID").equals(vo.getUid())) {
return true;
}
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
} catch (Exception e2) {
}
}
return false;
}
public boolean insert_user(PersonVO vo) {
//회원 가입
conn = JDBCUtill.connect();
try {
stmt = conn.prepareStatement(sql_insert);
stmt.setString(1, vo.getName()); //유저 이름
stmt.setString(2, vo.getUid()); //유저 아이디
stmt.setString(3, vo.getUpw()); //유저 비밀번호
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
return true;
} catch (Exception e2) {
}
}
return false;
}
public boolean update_user(PersonVO vo) {
//회원 비밀번호 변경
conn = JDBCUtill.connect();
try {
stmt = conn.prepareStatement(sql_update);
stmt.setString(1, vo.getUpw()); //유저 비밀번호
stmt.setInt(2, vo.getSid());
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
return true;
} catch (Exception e2) {
}
}
return false;
}
public boolean delete_user(PersonVO vo) {
//회원 탈퇴
conn = JDBCUtill.connect();
try {
stmt = conn.prepareStatement(sql_delete);
stmt.setInt(1, vo.getSid()); //유저 PK
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
return true;
} catch (Exception e2) {
}
}
return false;
}
public PersonVO loginCurret_user(PersonVO vo) {
//회원 로그인 성공
//id값을 비교하여 해당 정보 전달
conn = JDBCUtill.connect();
PersonVO data = null;
try {
stmt = conn.prepareStatement(sql_loginCurret);
stmt.setString(1, vo.getUid()); //유저 ID
stmt.executeUpdate();
ResultSet rs = stmt.executeQuery();
data = new PersonVO();
while (rs.next()) {
if(vo.getUid().equals(rs.getString("MID"))) {
//System.out.println("DATA값 넣기");
data.setSid(rs.getInt("SID"));
data.setName(rs.getString("NAME"));
data.setUid(rs.getString("MID"));
data.setUpw(rs.getString("MPW"));
break;
}
}
return data;
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
// return data;
} catch (Exception e2) {
}
}
return null;
}
public boolean logincheck_user(PersonVO vo) {
conn = JDBCUtill.connect();
try {
stmt = conn.prepareStatement(sql_logincheck);
stmt.setString(1, vo.getUid());
stmt.executeUpdate();
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
//중복검사에 없으면 참 아니면 거짓
if(rs.getString("MPW").equals(vo.getUpw())) {
//System.out.println(" LOG:로그인 성공");
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
JDBCUtill.disConnect(stmt, conn);
} catch (Exception e2) {
}
}
return false;
}
}
----------------------------EmartMallVO
package model;
public class EmartMallVO {
private int eId;
private int eCategory;
private String eName;
private int ePrice;
private int eReview;
private int maxPrice;
private int minPrice;
private String eImg;
private String Category;
public String getCategory() {
return Category;
}
public void setCategory(String category) {
Category = category;
}
public String geteImg() {
return eImg;
}
public void seteImg(String eImg) {
this.eImg = eImg;
}
public int geteId() {
return eId;
}
public void seteId(int eId) {
this.eId = eId;
}
public int geteCategory() {
return eCategory;
}
public void seteCategory(int eCategory) {
this.eCategory = eCategory;
}
public String geteName() {
return eName;
}
public void seteName(String eName) {
this.eName = eName;
}
public int getePrice() {
return ePrice;
}
public void setePrice(int ePrice) {
this.ePrice = ePrice;
}
public int geteReview() {
return eReview;
}
public void seteReview(int eReview) {
this.eReview = eReview;
}
public int getMaxPrice() {
return maxPrice;
}
public void setMaxPrice(int maxPrice) {
this.maxPrice = maxPrice;
}
public int getMinPrice() {
return minPrice;
}
public void setMinPrice(int minPrice) {
this.minPrice = minPrice;
}
@Override
public String toString() {
return "[번호: "+ eId + " 이름: "+ eName +" 금액: "+ ePrice
+"]";
}
}
----------------------------EmartMallDAO
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class EmartMallDAO {
Connection conn;
PreparedStatement pstmt;
final String sql_insert="INSERT INTO EPRODUCT VALUES((SELECT NVL(MAX(EID),0)+1 FROM EMARTMALL),?,?,?,?,?)";
final String sql_selectAll="SELECT * FROM EPRODUCT,ECATEGORY WHERE EPRODUCT.ECATEGORY=ECATEGORY.CID";
final String sql_condition="SELECT * FROM EPRODUCT,ECATEGORY WHERE EPRICE > ? AND EPRICE < ? AND EPRODUCT.ECATEGORY=ECATEGORY.CID ORDER BY ENAME ASC";
final String sql_selectOne="SELECT * FROM EPRODUCT,ECATEGORY WHERE EID=? AND EPRODUCT.ECATEGORY=ECATEGORY.CID";
final String sql_buyproduct="SELECT EPRODUCT.* ,CATEGORY FROM EPRODUCT,ECATEGORY WHERE EID=? AND EPRODUCT.ECATEGORY=ECATEGORY.CID";
final String sql_delete="DELETE FROM EPRODUCT WHERE EID=?";
final String sql_update="UPDATE EPRODUCT SET EREVIEW=? WHERE EID=?";
final String sql_img="SELECT EIMG FORM EPRODUCT WHERE EID=?";
final String sql_binsert="INSERT INTO BUYLIST VALUES((SELECT NVL(MAX(PID),0)+1 FROM BUYLIST),?,?)";
///////////////////////////////////////////////////////////////////////////////
// 카퉼고리
// public EmartMallVO category(EmartMallVO vo) {
// conn=model.JDBCUtill.connect(); // JDBCUtil을 연결
// ResultSet rs=null; // 캡슐화를 위해 의미없는 값을 넣어줌
// try {
// pstmt=conn.prepareStatement(sql_buyproduct);
// pstmt.setInt(1, vo.geteId()); // 쿼리내용의 첫번째 ?에 vo의 eid를 가져오겠다
// rs=pstmt.executeQuery(); // 데이터의 자동적인 변화
// if(rs.next()) { // 만약에 값이 있다면
// EmartMallVO data=new EmartMallVO();
// data.seteCategory(rs.getInt("eCategory"));
// return data; // 보여주기위해 값을 돌려줄것이다
// }
// else {
// return null; // 그게 아니라면 null값 돌려주기
// }
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// return null;
// } finally {
// try {
// rs.close();
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// model.JDBCUtill.disConnect(pstmt, conn);
// }
// }
///////////////////////////////////////////////////////////////////////////////
// 이미지
// public EmartMallVO imageLoad(EmartMallVO vo) {
// conn=model.JDBCUtill.connect(); // JDBCUtil을 연결
// ResultSet rs=null; // 캡슐화를 위해 의미없는 값을 넣어줌
// try {
// pstmt=conn.prepareStatement(sql_img);
// pstmt.setInt(1, vo.geteId());
// rs=pstmt.executeQuery();
// if(rs.next()) {
// EmartMallVO data=new EmartMallVO();
//
// data.seteId(rs.getInt("eId")); // PK값
// data.seteCategory(rs.getInt("eCategory"));
// data.seteName(rs.getString("eName")); // 출력값으로 이름
// data.setePrice(rs.getInt("sPrice"));
// data.seteReview(rs.getInt("eReview"));
// return data; // 보여주기위해 값을 돌려줄것이다
// }
// else {
// return null; // 그게 아니라면 null값 돌려주기
// }
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// return null;
// } finally {
// try {
// rs.close();
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// model.JDBCUtill.disConnect(pstmt, conn);
// }
// }
///////////////////////////////////////////////////////////////////////////////
// 상품 추가
public boolean insert(EmartMallVO vo) {
conn = model.JDBCUtill.connect();
try {
pstmt = conn.prepareStatement(sql_insert);
pstmt.setInt(1, vo.geteCategory());
pstmt.setString(2, vo.geteName());
pstmt.setInt(3, vo.getePrice());
pstmt.setInt(5, vo.geteReview());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// 전체상품 목록
public ArrayList<EmartMallVO> selectAll(EmartMallVO vo) {
ArrayList<EmartMallVO> datas = new ArrayList<EmartMallVO>();
conn = model.JDBCUtill.connect();
ResultSet rs;
try {
pstmt = conn.prepareStatement(sql_selectAll);
rs = pstmt.executeQuery();
while(rs.next()) {
EmartMallVO data = new EmartMallVO();
data.seteId(rs.getInt("eId"));
data.seteCategory(rs.getInt("eCategory"));
data.seteName(rs.getString("eName"));
data.setePrice(rs.getInt("ePrice"));
data.seteReview(rs.getInt("eReview"));
data.setCategory(rs.getString("Category"));
datas.add(data);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
return datas;
}
///////////////////////////////////////////////////////////////////////////////
// 상품가격 조건출력
public ArrayList<EmartMallVO> selectCon(EmartMallVO vo) {
ArrayList<EmartMallVO> datas = new ArrayList<EmartMallVO>();
conn = model.JDBCUtill.connect();
ResultSet rs;
try {
pstmt = conn.prepareStatement(sql_condition);
pstmt.setInt(1, vo.getMinPrice());
pstmt.setInt(2, vo.getMaxPrice());
rs = pstmt.executeQuery();
while(rs.next()) {
EmartMallVO data = new EmartMallVO();
data.seteId(rs.getInt("eId"));
data.seteCategory(rs.getInt("eCategory"));
data.seteName(rs.getString("eName"));
data.setePrice(rs.getInt("ePrice"));
data.seteReview(rs.getInt("eReview"));
data.setCategory(rs.getString("Category"));
datas.add(data);
}
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
return datas;
}
///////////////////////////////////////////////////////////////////////////////
// 상품 검색
public EmartMallVO selectOne(EmartMallVO vo) {
conn=model.JDBCUtill.connect(); // JDBCUtil을 연결
ResultSet rs=null; // 캡슐화를 위해 의미없는 값을 넣어줌
try {
pstmt=conn.prepareStatement(sql_selectOne);
pstmt.setInt(1, vo.geteId()); // 쿼리내용의 첫번째 ?에 vo의 eid를 가져오겠다
rs=pstmt.executeQuery(); // 데이터의 자동적인 변화
if(rs.next()) { // 만약에 값이 있다면
EmartMallVO data=new EmartMallVO();
data.seteId(rs.getInt("eId")); // PK값
data.seteCategory(rs.getInt("eCategory"));
data.seteName(rs.getString("eName")); // 출력값으로 이름
data.setePrice(rs.getInt("ePrice"));
data.seteReview(rs.getInt("eReview"));
data.seteImg(rs.getString("Eimg"));
return data; // 보여주기위해 값을 돌려줄것이다
}
else {
return null; // 그게 아니라면 null값 돌려주기
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} finally {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
model.JDBCUtill.disConnect(pstmt, conn);
}
}
///////////////////////////////////////////////////////////////////////////////
// 상품 삭제
public boolean deleteEmartMall(EmartMallVO vo) {
conn=model.JDBCUtill.connect();
try {
pstmt=conn.prepareStatement(sql_delete);
pstmt.setInt(1, vo.geteId()); // 1번째 물음표에 eid를 가져오겠다
int res=pstmt.executeUpdate(); // 데이터의 자동적인 변화
if(res==0) {
return false;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// 상품 갱신
public boolean updateEmartMall(EmartMallVO vo) {
conn=model.JDBCUtill.connect();
try {
pstmt=conn.prepareStatement(sql_update);
pstmt.setInt(1, vo.geteReview()); // 쿼리내용을 실행하기 위해 첫번째 ?에 vo의 review을 가져오겠다
pstmt.setInt(2, vo.geteId()); // 2번째 ?에 vo의 eid를 가져오겠다
int res=pstmt.executeUpdate(); // 데이터의 자동적인 변화
if(res==0) {
return false;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// 구매 목록 출력
public boolean binsert(PersonVO pvo, EmartMallVO evo) {
conn = model.JDBCUtill.connect();
try {
pstmt = conn.prepareStatement(sql_binsert);
pstmt.setInt(1, evo.geteId());
pstmt.setInt(2, pvo.getSid());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
return true;
}
}
----------------------------View
package view;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import model.EmartMallVO;
import model.PersonVO;
public class View {
Scanner sc=new Scanner(System.in);
Connection conn;
PreparedStatement pstmt;
EmartMallVO evo=null;
PersonVO pvo = null;
public int action;
public void inputDB(EmartMallVO vo,int i) { // DB에 크롤링 자료 넣기 i는 카테고리 번호(101~501)
conn=model.JDBCUtill.connect();
String sql_insert="INSERT INTO EPRODUCT VALUES((SELECT NVL(MAX(EID),0)+1 FROM EPRODUCT),?,?,?,"+i+",?)";
try {
pstmt=conn.prepareStatement(sql_insert);
pstmt.setString(1,vo.geteName()); // 이름
pstmt.setInt(2,vo.getePrice()); // 금액
pstmt.setInt(3,vo.geteReview()); // 리뷰수
pstmt.setString(4, vo.geteImg()); // 이미지
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
model.JDBCUtill.disConnect(pstmt, conn);
}
}
public void Crawling(String http,int i2) { // url과 카테고리 번호 입력
final String url=http;
Document doc=null;
try {
doc=Jsoup.connect(url).get();
} catch (IOException e) {
e.printStackTrace();
}
Elements eles=doc.select("ul>li.cunit_t232>div>div>div>a>em.tx_ko"); // 이름
Elements eles2=doc.select("ul>li.cunit_t232>div>div>div>em.ssg_price"); // 금액
Elements eles3=doc.select("ul>li.cunit_t232>div>div>div>span>em"); // 리뷰수
Elements eles4=doc.select("ul>li.cunit_t232>div>div.thmb>a>img.i1"); // 이미지
Iterator<Element> itr=eles.iterator(); //이름
Iterator<Element> itr2=eles2.iterator(); //금액
Iterator<Element> itr3=eles3.iterator(); //리뷰수
Iterator<Element> itr4=eles4.iterator(); //이미지
for(int i=0;i<20;i++) {
String str=itr.next().text();
String str2=itr2.next().text();
String str3=itr3.next().text();
String str4=itr4.next().attr("src");
EmartMallVO vo=new EmartMallVO();
System.out.println(str);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
vo.seteName(str); //이름
vo.setePrice(Integer.parseInt(str2.replaceAll("[^0-9]", ""))); //금액
vo.seteReview(Integer.parseInt(str3.replaceAll("[^0-9]", ""))); //리뷰수
vo.seteImg(str4); // 이미지
this.inputDB(vo,i2); // insert에 vo 입력
}
// System.out.println("로그: DB에 저장완료!");
}
public void startView() { // 첫 화면 출력
while(true) {
System.out.println("====Emart Mall에 오신것을 환영합니다!====");
System.out.println("1.로그인");
System.out.println("2.회원가입");
System.out.println("3.종료");
System.out.print("입력 :");
try {
action=sc.nextInt(); // action은 멤버변수를 사용하면 됨
if(action>=1 && action<=3) { // 입력값 제한
return;
}else {
System.out.println("범위 외 입력입니다. 다시 입력해주세요.");
}
}catch(Exception e) {
System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
}
}
}
public void logIn() { // 로그인 알림
System.out.println("====로그인====");
}
public void join() { // 회원가입 알림
System.out.println("====회원가입====");
}
public String joinName() { //이름 입력, 입력한 이름 String으로 반환
System.out.print("이름 :");
String name=sc.next();
return name;
}
public String inputID() { //ID입력,String으로 반환
System.out.print("ID :");
String id=sc.next();
return id;
}
public void chId() { //아이디가 존재하지 않을 시
System.out.println("회원정보가 없습니다. 다시 로그인해주세요.");
System.out.println();
}
public void exId() {
System.out.println("존재하는 id입니다. 다시 입력해주세요.");
}
public String inpuPw() { //비밀번호 입력 및 체크, 체크 후 String으로 반환,체크안되면 null
System.out.print("비밀번호 :");
String pw=sc.next();
System.out.print("비밀번호 확인 :");
String chPw=sc.next();
if(pw.equals(chPw)) {
return pw;
}
this.checkPw();
return null;
}
public void checkPw() { // 비밀번호 일치하지 않을시 출력
System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
}
public void successJoin() { // 회원가입 완료 안내
System.out.println("회원가입이 완료되었습니다!");
}
public String loginPw() { //비밀번호 입력,String으로 반환
System.out.print("비밀번호 : ");
String pw=sc.next();
return pw;
}
public void exit() { //프로그램 종료
System.out.print("프로그램을 종료합니다");
for (int i = 0; i < 5; i++) {
System.out.print(".");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println();
System.out.println("이용해주셔서 감사합니다.");
}
public void welcome(PersonVO vo) {
System.out.println(vo.getName()+"님 어서오세요!");
}
public void mainView() { // 로그인 후 메인화면
while(true) {
System.out.println("===EmartMall에 오신것을 환영합니다!===");
System.out.println("1.상품목록");
System.out.println("2.상품검색");
System.out.println("3.마이페이지");
System.out.println("4.로그아웃");
System.out.print(">> ");
try {
action=sc.nextInt();
if(action>=1&&action<=4) { //입력값 제한
return;
}
System.out.println("범위 외 입력입니다. 다시 입력해주세요.");
}catch(Exception e) {
System.out.println("잘못된 입력입니다.다시입력해주세요.");
}
}
}
public void printList(ArrayList<EmartMallVO> datas) { //리스트의 모든 상품 출력
System.out.println("====상품 목록====");
for (int i = 0; i < datas.size(); i++) {
System.out.println("번호 :"+datas.get(i).geteId()+" 상품명 :"+datas.get(i).geteName()+" 가격 :"+datas.get(i).getePrice()+
" 구매횟수 :"+datas.get(i).geteReview()+" 카테고리 :"+datas.get(i).getCategory());
}
}
public void printOne(EmartMallVO vo) { // 상품 1개 출력
System.out.println("번호 :"+vo.geteId()+" 상품명 :"+vo.geteName()+" 가격 :"+vo.getePrice()+
" 구매횟수 :"+vo.geteReview()+" 카테고리 :"+vo.getCategory());
}
public void searchView() { //상품검색 안내
System.out.println("====상품검색====");
}
public int inputMinPrice() { //금액입력,int로 반환
System.out.print("최소금액입력 :");
int price=sc.nextInt();
return price;
}
public int inputMaxPrice() { //금액입력,int로 반환
System.out.print("최대금액입력 :");
int price=sc.nextInt();
return price;
}
public int inputNum() { //번호입력,int로 반환
System.out.print("번호입력 :");
int num=sc.nextInt();
return num;
}
public String YorN() { //Y or N 모든 입력을 대문자로 바꿔서 검사
while(true) {
System.out.print("구매하시겠습니까?(Y/N) :");
try {
String ans=sc.next();
if(!(ans.toUpperCase().equals("Y")||ans.toUpperCase().equals("N"))) {
System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
continue;
}
return ans.toUpperCase();
}catch(Exception e) {
System.out.println("문자열만 입력 가능합니다.");
}
}
}
public void mypageView(PersonVO pvo) { // 마이페이지
while(true) {
System.out.println(pvo.getName()+"님 어서오세요.");
System.out.println("====마이페이지====");
System.out.println("1.구매상품");
System.out.println("2.비밀번호변경");
System.out.println("3.회원탈퇴");
System.out.println("4.나가기");
System.out.print(">> ");
try {
action=sc.nextInt();
if(action>=1&&action<=4) { //입력값 제한
return;
}
System.out.println("범위 외 입력입니다. 다시 입력해주세요.");
}catch(Exception e) {
System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
}
}
}
public void myProduct() { // 내가 구매한 상품
System.out.println("===구매상품===");
// 장바구니 시스템인데..
}
public void buyZero() {
System.out.println("구매한 목록 없음...");
}
// 출력 로직 추가
public void buyList(ArrayList<EmartMallVO> vo) {
for (int i = 0; i < vo.size(); i++) {
System.out.println(vo.get(i));
}
}
public void changePw() { // 비밀번호 변경
System.out.println("===비밀번호변경===");
}
public void deleteUser() { // 회원탈퇴
System.out.println("===회원탈퇴===");
}
public void success() { // 성공
System.out.println("수행성공!");
}
public void fail() { // 실패
System.out.println("수행실패..");
}
public void insSucc() {
System.out.println("구매목록에 등록되었습니다.");
}
public void insFail() {
System.out.println("구매목록 등록에 실패하였습니다.");
}
}
----------------------------Test
package view;
public class Test {
public static void main(String[] args) {
String str1="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095739"; //과일
String str2="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095740";//채소
String str3="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095499"; //정육
String str4="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095500"; //수산물
String str5="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095505"; //과자
View view=new View();
//
view.Crawling(str1,101);
view.Crawling(str2,201);
view.Crawling(str3,301);
view.Crawling(str4,401);
view.Crawling(str5,501);
}
}
----------------------------Program
package view;
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;
import model.EmartMallDAO;
import model.EmartMallVO;
public class Program extends JFrame{
JTextField tf1, tf2, tfUrl;
JButton btCopy, btUrlCopy; JProgressBar pb; JLabel lbImage;
FileInputStream fis; FileOutputStream fos;
File file1, file2;
public Program(EmartMallVO vo) { // vo를 입력으로 받아 vo가 가진 img를 출력
super("::Program::");
Container cp = getContentPane();
JPanel p = new JPanel(new GridLayout(0,1));
cp.add(p);
lbImage=new JLabel("", JLabel.CENTER);
cp.add(new JScrollPane(lbImage));
lbImage.setBorder(new LineBorder(Color.magenta));
tf2=new JTextField("target.jpg");
tfUrl=new JTextField("https:"+vo.geteImg());
btUrlCopy=new JButton("출력");
pb=new JProgressBar();
JPanel p2 = new JPanel(); p.add(p2);
p2.add(btUrlCopy);
p.setBorder(new BevelBorder(BevelBorder.RAISED)); // 패널을 입체적으로 보여줌
// 인터넷 이미지 url 주소의 이미지를 복사하는 버튼 이벤트 리스너
String urlStr = tfUrl.getText();
urlFileCopy(urlStr); // 사용자 정의 메소드
new Thread(){
}.start();
setSize(500, 800);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public synchronized void fileCopy(File srcFile, File tarFile){
// 스트림 연결 => 노드 스트림 => 필터 스트림
String msg="";
long fsize=srcFile.length(); // 원본 파일의 크기를 반환
setTitle("원본 파일 크기 : "+fsize+"bytes");
//pb의 최대값을 원본 파일 크기로 잡는다.
pb.setMaximum(0); pb.setMaximum((int)fsize);
try{
fis = new FileInputStream(srcFile);
fos = new FileOutputStream(tarFile);
//BuffredInputStream으로 처리하면 더 빠르다
// 반복문 돌면서 읽어들이고 내보낸다.
int input=0, count=0;
byte[] data = new byte[1024];
// 원본 이미지 복사
while((input=fis.read(data))!=-1){
fos.write(data, 0, input);
fos.flush();
count+=input;
pb.setValue(count);
Thread.sleep(10);
}
msg=count+"bytes 카피 완료";
// 스트림 닫기
fis.close(); fos.close();
lbImage.setIcon(new ImageIcon(tarFile.getAbsolutePath()));
}catch(FileNotFoundException e){
msg="없는 파일이에요: "+e.getMessage();
}catch(InterruptedException e){
msg="Interrupted 오류"+e.getMessage();
}catch(IOException e){
msg="오류 : "+e.getMessage();
}
JOptionPane.showMessageDialog(this, msg);
}
public void urlFileCopy(String urlStr){
// throws로 하면 다른 쪽에서 예외 처리를 해줘야함
try{
java.net.URL url = new java.net.URL(urlStr);
InputStream is = url.openStream();
java.net.URLConnection con = url.openConnection();
// url에 있는 파일의 크기를 반환한다.
int fsize = con.getContentLength();
setTitle(fsize+"bytes");
// 해당 url과 노드 연결된 입력 스트림을 반환한다.
BufferedInputStream bis = new BufferedInputStream(is);
file2 = new File(tf2.getText());
fos = new FileOutputStream(file2);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int input=0, count=0;
byte[] data = new byte[3000];
while((input=bis.read(data))!=-1){
bos.write(data, 0, input);
bos.flush();
count+=input;
pb.setValue(count);
Thread.sleep(10);
}
bis.close(); bos.close();
is.close(); fos.close();
lbImage.setIcon(new ImageIcon(file2.getAbsolutePath()));
}catch(MalformedURLException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
View v=new View();
EmartMallVO vo=new EmartMallVO();
EmartMallDAO dao=new EmartMallDAO();
new Program(dao.selectOne(vo)); // vo에 담겨있는 img를 화면으로 출력
}
}
----------------------------Controller
package controller;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import model.EmartMallDAO;
import model.EmartMallVO;
import model.PersonDAO;
import model.PersonVO;
import view.View;
import view.Program;
public class Controller {
View eview;
EmartMallVO evo;
EmartMallDAO edao;
PersonVO pvo;
PersonDAO pdao;
PersonVO uservo;
ArrayList<PersonVO> arr = new ArrayList<PersonVO>();
final String sql_binsert="INSERT INTO BUYLIST VALUES((SELECT NVL(MAX(BID),0)+1 FROM BUYLIST),?,?)";
// final String sql_bupdate="UPDATE BUYLIST SET BITEM = ? WHERE BNAME = ?";
// final String sql_select="SELECT BUYLIST.*,USERDATA.NAME,EPRODUCT.* FROM BUYLIST,USERDATA,EPRODUCT WHERE BUYLIST.BNAME=? AND BUYLIST.BNAME=USERDATA.SID AND BUYLIST.BITEM=EPRODUCT.EID";
// final String sql_buyproduct="SELECT EPRODUCT.* ,CATEGORY FROM EPRODUCT,ECATEGORY WHERE EPRODUCT.ECATEGORY=ECATEGORY.CID";
Connection conn = null;
PreparedStatement pstmt = null;
public Controller() {
eview = new View();
evo = new EmartMallVO();
edao = new EmartMallDAO();
pvo = new PersonVO();
pdao = new PersonDAO();
uservo = new PersonVO();
// String str1="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095739"; //과일
// String str2="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095740";//채소
// String str3="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095499"; //정육
// String str4="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095500"; //수산물
// String str5="https://emart.ssg.com/category/main.ssg?dispCtgId=6000095505"; //과자
//
// eview.Crawling(str1,101);
// this.deley();
// eview.Crawling(str2,201);
// this.deley();
// eview.Crawling(str3,301);
// this.deley();
// eview.Crawling(str4,401);
// this.deley();
// eview.Crawling(str5,501);
}
public void deley() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void appStart() { // 로그인화면
while(true) {
eview.startView();
if(eview.action==1) { // 로그인 화면
eview.logIn();
String id = eview.inputID();
pvo.setUid(id);
//System.out.println(pvo.getUid() + "로그 : id 입력");
String pw = eview.loginPw();
pvo.setUpw(pw);
//System.out.println(pvo.getUpw() + "로그 : pw 입력");
if(pdao.logincheck_user(pvo)) {
//System.out.println(" 로그 : id,pw 입력 후 로그인");
uservo = pdao.loginCurret_user(pvo);
mainMenu();
}else {
eview.chId();
continue;
}
}
else if(eview.action==2) { // 회원가입 화면
eview.join();
String name = eview.joinName(); // 이름 입력
pvo.setName(name);
while(true) {
String id = eview.inputID(); // id 입력
pvo.setUid(id);
if(pdao.idcheck_user(pvo)) {
eview.exId();
continue;
}
else {
break;
}
}
while(true) { // pw 입력
String pw = eview.inpuPw();
if(pw==null) {
continue;
}
else {
pvo.setUpw(pw);
break;
}
}
if(pdao.insert_user(pvo)) {
eview.successJoin();
continue;
}
else {
eview.fail();
continue;
}
}
else {
eview.exit();
break;
}
}
}
public void mainMenu() { // 메인메뉴
while(true) {
eview.welcome(uservo);
eview.mainView();
if(eview.action==1) {
// 목록
EmartMallVO vo = new EmartMallVO();
ArrayList<EmartMallVO> datas = edao.selectAll(vo);
// 목록 출력
eview.printList(datas);
}
else if(eview.action==2) {
// 검색 -> 구매까지
evo.setMinPrice(eview.inputMinPrice());
evo.setMaxPrice(eview.inputMaxPrice());
ArrayList<EmartMallVO> datas = edao.selectCon(evo);
eview.printList(datas);
// 구매할 상품번호 입력
evo.seteId(eview.inputNum());
EmartMallVO vo2=edao.selectOne(evo);
new Program(vo2);
if(eview.YorN().equals("Y")) {
vo2.seteReview(vo2.geteReview()+1);
edao.updateEmartMall(vo2);
eview.success();
if(edao.binsert(uservo,evo)){
eview.insSucc();
continue;
}
else {
eview.insFail();
continue;
}
//continue;
}
else {
eview.fail();
continue;
}
}
else if(eview.action==3) {
myPage();
}
else {
eview.exit();
uservo = null;
break;
}
}
}
public void myPage() { // 유저 마이페이지
while(true) {
// eview.welcome(uservo);
eview.mypageView(uservo);
if(eview.action==1) {
eview.myProduct();
// System.out.println(uservo.getSid());
ArrayList<EmartMallVO> datas=pdao.buylist_user(uservo);
if(datas.size()==0) {
eview.buyZero();
continue;
}
eview.buyList(datas);
continue;
}
else if(eview.action==2) {
eview.changePw();
while(true) { // pw 입력
String pw = eview.inpuPw();
if(pw==null) {
continue;
}
else {
uservo.setUpw(pw);
break;
}
}
if(pdao.update_user(uservo)) {
eview.success();
continue;
}else {
eview.fail();
continue;
}
}
else if(eview.action==3) {
eview.deleteUser();
if(pdao.delete_user(uservo)) {
eview.success();
uservo = null;
appStart();
}
else {
eview.fail();
continue;
}
}
else {
break;
}
}
}
}
----------------------------Client
package controller;
public class Client {
public static void main(String[] args) {
Controller app = new Controller();
app.appStart();
}
}
-----------------------------EMARTSQL
CREATE TABLE ECATEGORY(
CID INT PRIMARY KEY,
CATEGORY VARCHAR(20)
);
CREATE TABLE EPRODUCT(
EID INT PRIMARY KEY,
ENAME VARCHAR(200) NOT NULL,
EPRICE INT DEFAULT 0,
EREVIEW INT DEFAULT 0,
ECATEGORY INT DEFAULT 0,
EIMG VARCHAR(500) NOT NULL
);
CREATE TABLE USERDATA(
SID INT PRIMARY KEY,
NAME VARCHAR(200) NOT NULL,
MID VARCHAR(200) UNIQUE NOT NULL,
MPW VARCHAR(200) NOT NULL
);
CREATE TABLE BUYLIST(
PID INT PRIMARY KEY,
EID INT,
SID INT
);
DROP TABLE EPRODUCT;
DROP TABLE BUYLIST;
DROP TABLE USERDATA;
DELETE FROM BUYLIST A WHERE NOT EXISTS(SELECT SID FROM USERDATA B WHERE A.SID = B.SID);
INSERT INTO USERDATA VALUES((SELECT NVL(MAX(SID),0)+1 FROM USERDATA),'관리자','ADMIN','1111');
SELECT * FROM USERDATA;
INSERT INTO BUYLIST VALUES((SELECT NVL(MAX(BID),0)+1 FROM BUYLIST),?,?);
UPDATE BUYLIST SET BITEM = ? WHERE BNAME = ?;
SELECT * FROM USER_TABLES;
SELECT * FROM USERDATA;
SELECT * FROM EPRODUCT;
SELECT * FROM ECATEGORY;
SELECT * FROM BUYLIST;
DROP TABLE USERDATA;
DROP TABLE BUYLIST;
INSERT INTO ECATEGORY VALUES((SELECT NVL(MAX(CID),1)+100 FROM ECATEGORY),'과일');
INSERT INTO ECATEGORY VALUES((SELECT NVL(MAX(CID),1)+100 FROM ECATEGORY),'채소');
INSERT INTO ECATEGORY VALUES((SELECT NVL(MAX(CID),1)+100 FROM ECATEGORY),'정육');
INSERT INTO ECATEGORY VALUES((SELECT NVL(MAX(CID),1)+100 FROM ECATEGORY),'수산물');
INSERT INTO ECATEGORY VALUES((SELECT NVL(MAX(CID),1)+100 FROM ECATEGORY),'과자');
SELECT ENAME,CATEGORY FROM EPRODUCT,ECATEGORY WHERE EPRODUCT.ECATEGORY=ECATEGORY.CID;
SELECT BUYLIST.*,USERDATA.NAME,EPRODUCT.* FROM BUYLIST,USERDATA,EPRODUCT WHERE BUYLIST.BNAME=? AND BUYLIST.BNAME=USERDATA.SID AND BUYLIST.BITEM=EPRODUCT.EID;
[2Quals 팀원]
조장 손성환님 - View파트
조원 성해성님 - Model파트
조원 이경준님 - Model파트
조원 연은주님 - Controller파트
조원 노유림(나) - Controller파트
이번 팀 과제도 고생하셨습니다!
'0607 팀 프로젝트 - 2Quals' 카테고리의 다른 글
[팀 프로젝트] - 펫 상점(펫키지) 1일차 회의 기록(MVC 파트 구분, 요구사항 분석, User Flow 페이지 개수, 테이블 개수) (0) | 2022.08.17 |
---|---|
[팀 프로젝트] - 펫 상점(개밥집) 사용 API (0) | 2022.08.05 |
7/12 팀 프로젝트 발표 - 2quals 자판기 pdf + 각 팀 좋은 점(참고) (0) | 2022.07.12 |
7/6~7/11 팀 프로젝트 - View 파트(사용자모드 + 약간의 관리자모드) 정리 (0) | 2022.07.12 |
6/28~7/5 밀린 팀프로젝트 정리 (0) | 2022.07.05 |