2018-7-31 크롤러 데이터처리
@Service
public class StockService {
public static final Logger logger = LoggerFactory.getLogger(StockService.class);
@Resource(name = "stockRepository")
private StockRepository stockRepository;
public List<Stock> findAll() {
return stockRepository.findAll();
}
public Stock findById(long id) {
return stockRepository.findOne(id);
}
public Stock findByName(String stockName) {
logger.info("stockName on Service : {}", stockName);
return stockRepository.findByName(stockName);
}
public Stock add(String stockName) throws Exception {
Research research = new Research(stockName);
return stockRepository.save(research.update(stockRepository.findByName(stockName.toUpperCase()), checkMakingStock(stockName)));
}
public boolean checkMakingStock(String stockName) {
Stock stock = stockRepository.findByName(stockName.toUpperCase());
if (stock != null && stock.getDiffday() < 15)
return true;
logger.info("stockName : {}", stockName);
return false;
}
@Transactional
public void delete(long id) throws Exception {
logger.info("delete method called {}", id);
stockRepository.delete(id);
}
}
@Service
public class Research {
public static final Logger logger = LoggerFactory.getLogger(Research.class);
private WebDriver driver;
private String stockName;
private String price;
private String changeMoney;
private String changePercent;
public Research() {}
public Research(String stockName) {
this.stockName = stockName.toUpperCase();
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
System.setProperty("webdriver.chrome.driver", "/Users/jaeyeonkim/Desktop/web-crawler/src/main/java/com/example/demo/chromedriver");
driver = new ChromeDriver(options);
String startUrl = "http://finance.daum.net/";
driver.get(startUrl);
}
public String search() {
driver.findElement(By.id("name")).sendKeys(getStockName());
driver.findElement(By.id("daumBtnSearch")).click();
WebElement element = driver.findElement(By.cssSelector("a[title="+getStockName()+"]"));
String detailUrl = element.getAttribute("href");
return detailUrl;
}
public Stock update(Stock original, boolean check) {
driver.get(search());
price = driver.findElement(By.xpath("//*[@id=\"topWrap\"]/div[1]/ul[2]/li[1]/em")).getText();
changeMoney = driver.findElement(By.xpath("//*[@id=\"topWrap\"]/div[1]/ul[2]/li[2]/span")).getText();
changePercent = driver.findElement(By.xpath("//*[@id=\"topWrap\"]/div[1]/ul[2]/li[3]/span")).getText();
if (!check)
return make();
original.update(price, changeMoney, changePercent);
logger.info("update info : {}", original.toString());
return original;
}
public Stock make() {
String salesMoney = driver.findElement(By.xpath("//*[@id=\"performanceCorp\"]/table/tbody/tr[4]/td[9]")).getText();
String totalCost = driver.findElement(By.xpath("//*[@id=\"stockContent\"]/ul[2]/li[2]/dl[2]/dd")).getText();
String yearProfit = driver.findElement(By.xpath("//*[@id=\"performanceCorp\"]/table/tbody/tr[5]/td[9]")).getText();
return new Stock(getStockName(), getPrice(), salesMoney, yearProfit, totalCost, getChangeMoney(), getChangePercent(), search());
}
public String getPrice() {
return price;
}
public String getChangeMoney() {
return changeMoney;
}
public String getChangePercent() {
return changePercent;
}
public String getStockName() {
return stockName;
}
}
- 크롤러에서 주식에 관한 정보를 가지고 올때, 실시간가격 변동률 변동가격 등은 실시간으로 변하는 데이터이다. 하지만 영업이익 매출액과 같은 데이터는 변동이 거의없다.
- 2개의 데이터로 나누었다. 변하는 데이터와 자주안변하는 데이터로 구분을 해서. 자주안변하는 데이터에 대해서는 데이터베이스에 값을 넣고 가지고 오는 형태로, 실시간으로 변하는 데이터는 크롤링을 하는 형태로 구분을 해서 Stock객체를 생성을 한다.
- Stock객체는 CreateDate, ModifiedDate로 구분이되어서, 현재시각과 비교를 해서 업데이트 날짜와 현재날짜의 차이가 기준시간보다 클 경우 새로 업데이틀르 하고 그렇지 않은경우에는 실시간데이터만 가지고와서 처리를 한다.
Written on July 31, 2018