package craw;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import testDTO.Naver_Map_CrawlingDTO;
public class CrawlingTest10{
public static ArrayList<Naver_Map_CrawlingDTO> crawling(String search,int page) {
//page 는 무조건 있어야 하니
//만약 0보다 작다면 1로 고정
if(page <= 0) {
page = 1;
}
// ChromeOptions 객체 생성
ChromeOptions options = new ChromeOptions();
// 헤드리스 모드 설정
// options.addArguments("--headless");
// 추가적인 옵션 설정 (선택 사항)
options.addArguments("--disable-gpu"); // GPU 비활성화 (일부 환경에서 필요)
options.addArguments("--window-size=1920,1080"); // 브라우저 창 크기 설정
options.addArguments("--no-sandbox"); // 샌드박스 모드 비활성화 (Linux에서 권장)
options.addArguments("--disable-dev-shm-usage"); // /dev/shm 사용 비활성화 (메모리 문제 해결)
WebDriver driver = new ChromeDriver(options);
//--------------------------------------------------------------------------------
//최종적으로 저장할 공간
ArrayList<Naver_Map_CrawlingDTO> datas = new ArrayList<Naver_Map_CrawlingDTO>();
//가져온 이미지 주소를 담을 배열
ArrayList<String> naver_map_climbing_img = new ArrayList<String>();
//가져온 이름을 담을 배열
ArrayList<String> naver_map_climbing_name = new ArrayList<String>();
//가져온 주소를 담을 배열
ArrayList<String> naver_map_climbing_address = new ArrayList<String>();
//이미지 요소를 담을 변수
WebElement climbing_img_Element = null;
//이름 요소를 담을 변수
WebElement climbing_name_Element = null;
//주소 div 태그를 열기 위함 요소를 담을 변수
WebElement climbing_address_div_Element = null;
//주소 요소를 담을 변수
WebElement climbing_address_Element = null;
//주소 담을 동안 div 태그를 클릭하여 스크롤이 내려가므로 필요가 없어졌음
//JavascriptExecutor js = (JavascriptExecutor) driver;
//--------------------------------------------------------------------------------
// 주소 설정
String url = "https://www.naver.com/";
// 웹 페이지 접속
driver.get(url);
driver.manage().window().maximize();
// 현재 ChromeDriver의 대기 시간 2초를 부여
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
//----------------------------------------------------------------------------------
//네이버 지도를 들어가기 위한 준비
//naver 접속 후 지도를 클릭
WebElement map = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#shortcutArea > ul > li:nth-child(8) > a")));
System.out.println("map로그 : "+map);
map.click();
//열린 창 OR 탭을 가져오는 코드
Set<String> naver_map = driver.getWindowHandles();
String current_naver_map = driver.getWindowHandle();
// 새로 열린 창으로 전환하기 위한 for 문
for (String window : naver_map) {
//현재 열려 있는 창중 처음 열린 창과 다르다면
if (!window.equals(current_naver_map)) {
//현재 창을 새로열린 창으로 변경하여 저장하고
current_naver_map = window;
//새로 열린 창으로 전환해줍니다.
driver.switchTo().window(window); // 새로운 창으로 전환
break;//전환 후 for 문 종료
}
}
//지도가 열렸다면 검색 input 태그를 불러와 줍니다.
WebElement search_value = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div > div > div > .input_search")));
//받아온 검색 값을 확인하기 위한 로그
System.out.println("검색 로그 : "+search);
search_value.sendKeys(search);
search_value.sendKeys(Keys.ENTER);
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
// Iframe 요소를 가져와줍니다.
WebElement climbing_iframe = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#searchIframe")));
System.out.println(climbing_iframe);
// 찾은 Iframe 요소의 주소만 불러와 현재 창을 전환해 줍니다.
driver.get(climbing_iframe.getAttribute("src"));
//----------------------------------------------------------------------------------
System.out.println("로그 : 크롤링 시작");
for(int page_num = 0; page_num < page; page_num++) {
System.out.println("--------------------------Iframe 페이지 요소 찾기----------------------------");
//크롤링 성능을 올리기 위해 xPath로 이름 요소를 찾고 try catch는 페이지 이동 처음에 배치
try {
climbing_name_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[3]/div/div[2]/div[1]/ul/li[1]/div[1]/div[2]/a[1]/div/div/span[1]")));
System.out.println(climbing_name_Element.getText() + " 1 요소");
}catch (Exception e) {
climbing_name_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("html/body/div[3]/div/div[2]/div[1]/ul/li[1]/div[1]/div/a[1]/div/div/span[1]")));
System.out.println(climbing_name_Element.getText() + " 2 요소");
}
System.out.println("-------------------------------------------------------------------");
for (int i = 1; i < 40; i++) {
//#_pcmap_list_scroll_container > ul > li:nth-child(1) > div.qbGlu > div.ouxiq > a:nth-child(1) > div > div > span.YwYLL
climbing_name_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#_pcmap_list_scroll_container > ul > li:nth-child("+i+") > div.qbGlu > div.ouxiq > a:nth-child(1) > div > div > span.YwYLL")));
//이름 불러오기
System.out.println(climbing_name_Element.getText());
naver_map_climbing_name.add(climbing_name_Element.getText());
//상세 주소를 가져오기 위해 주소요소를 클릭
climbing_address_div_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("li:nth-child("+i+") > div.qbGlu > div.ouxiq > div > div > span:nth-child(2) > a")));
climbing_address_div_Element.click();
//li:nth-child(1) > div.qbGlu > div.ouxiq > div > div > div > div > div:nth-child(1)
climbing_address_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("li:nth-child("+i+") > div.qbGlu > div.ouxiq > div > div > div > div > div:nth-child(1)")));
//주소 불러오기
System.out.println(climbing_address_Element.getText());
naver_map_climbing_address.add(climbing_address_Element.getText().replace("지번", "").replace("도로명", "").replace("복사", ""));
//이미지 불러오기
try {
//#_pcmap_list_scroll_container > ul > li:nth-child(1) > div.qbGlu > div.TTfa9 > a > img
climbing_img_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("li:nth-child("+i+") > div.qbGlu > div.TTfa9 > a > img")));
//현재 찾은 img 요소가 어떤것인지 확인하기 위해 작성
System.out.println("현재 요소 : "+climbing_img_Element);
System.out.println(climbing_img_Element.getAttribute("src"));
naver_map_climbing_img.add(climbing_img_Element.getAttribute("src"));
}catch (Exception e) {
try {
//#_pcmap_list_scroll_container > ul > li:nth-child(2) > div.qbGlu > div.TTfa9 > a > div > img
climbing_img_Element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("li:nth-child("+i+") > div.qbGlu > div.TTfa9 > a > div > img")));
//현재 찾은 img 요소가 어떤것인지 확인하기 위해 작성
System.out.println("현재 요소 : "+climbing_img_Element);
System.out.println(climbing_img_Element.getAttribute("src"));
naver_map_climbing_img.add(climbing_img_Element.getAttribute("src"));
}catch (Exception ex) {
naver_map_climbing_img.add("");
System.out.println("img 태그 오류 발생 저장X : "+i+"번");
}
}
//div 태그 클릭해서 스크롤 이동이 가능하므로 JavaScript가 필요 없습니다.
//js.executeScript("arguments[0].scrollIntoView(true);", climbing_name_Element);
}
try {
WebElement next_map = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#app-root > div > div.XUrfU > div.zRM9F > a:nth-child(7)")));
next_map.click();
} catch (Exception e) {
//페이지 네이션을 선택할때 오류가 발생한다면 종료
break;
}
}
//실제 데이터 저장하기 위한 for문
for (int i = 0; i < naver_map_climbing_name.size(); i++) {
Naver_Map_CrawlingDTO data = new Naver_Map_CrawlingDTO();
data.setNaver_map_climbing_address(naver_map_climbing_address.get(i).toString());
data.setNaver_map_climbing_img(naver_map_climbing_img.get(i));
data.setNaver_map_climbing_name(naver_map_climbing_name.get(i));
// 저장되고 있는지 확인용 코드
//System.out.println("datas 저장중 "+naver_map_climbing_img.get(i));
//이미지는 필수로 필요하니 이미지가 없는 요소들은 실질적으로 저장하지 않음
if(!naver_map_climbing_img.get(i).equals("")) {
datas.add(data);
}
}
// 아래 두 코드는 탭 OR 창 전환 후 원래 창으로 돌아오는 코드이나.
// 지도 크롤링 완료 후
// 기본 컨텐츠로 전환
//driver.switchTo().defaultContent();
// 작업이 끝난 후, 원래 창으로 돌아오기
//driver.switchTo().window(current_naver_map);
//드라이버 종료
driver.quit();
System.out.println(datas);
return datas;
}
// 크롤링 확인용
public static void main(String[] args) {
CrawlingTest10.crawling("클라이밍",2);
}
}
728x90
'추가 공부 > Web' 카테고리의 다른 글
CKEditor5 사용해보기 1 (1) | 2024.09.17 |
---|---|
CKEditor5 연동 (1) | 2024.09.15 |
JAVA에서 mkdir 사용해보기 (0) | 2024.09.10 |
JSP Selenium 사용해보기 2 (3) | 2024.09.03 |
JSP Selenium 사용해보기 1 (0) | 2024.09.02 |