728x90
결과
위 이미지에 포함되지 않았지만 카카오
를 검색했을 때 나오는 2000 여개
의 결과를 모두 크롤링했다.
코드
사람인
사이트에서 크롤링하는 코드를 아래와 같이 수정했다.
1) 페이지 번호를 옮기기 위해서 recruitPage
파라미터를 추가했다. 반복이 시작될 때 마다 페이지 번호를 1씩 증가시킨다.
2) 크롤링을 위해서 By.cssSelector()
메소드를 사용했다. 이 메소드를 사용하면 원하는 html의 구조에 따라서 크롤링할 수 있기 때문이다.
package org.example.springboot.web.recruiteWebSite;
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class SaramIn {
// 파라미터 str = 검색 url
// 일단, 채용정보 1페이지에 있는 내용만 출력하도록 하자.
// 채용정보 파라미터는 recruitPage. company 뒤에 &로 이어서 전달하면 된다.
// ex) 2페이지 - recruitPage = 2
public static String saramInSearch(String str) throws IOException {
String result = "";
WebDriver driver;
final String WEB_DRIVER_ID = "webdriver.chrome.driver";
final String WEB_DRIVER_PATH = "C:/devtool/chromedriver_win32/chromedriver.exe"; // 크롬 드라이버 경로
String base_url; // 크롤링 할 url
// System Property 설정
System.setProperty(WEB_DRIVER_ID, WEB_DRIVER_PATH);
driver = new ChromeDriver();
base_url = str + "&recruitPage="; // 페이지 번호 매개변수를 추가한 url
List<WebElement> titleList = new LinkedList<WebElement>();
List<WebElement> companyList = new LinkedList<WebElement>();
try {
int pageNumber = 1;
int prevCount = 0;
while(true) {
// 반복문이 돌아올 때 마다 페이지 번호를 1씩 증가시킨다.
driver.get(base_url + Integer.toString(pageNumber++));
// item_recruit라는 이름의 클래스 리스트를 불러옴
// <div id = "recruit_info_list"> -> <div class = "content">
// -> <div class = "item_recruit"> -> <div class = "area_job"> -> <h2 class = "job_tit">
titleList = driver.findElements(
By.cssSelector("#recruit_info_list > div.content > div.item_recruit > div.area_job > h2.job_tit"));
companyList = driver.findElements(
By.cssSelector("#recruit_info_list > div.content > div.item_recruit > div.area_corp > strong.corp_name"));
// 더 이상 검색결과가 없을 때까지 반복한다.
if(titleList.size() == 0) break;
try {
for(int i = 0; i < titleList.size(); i++) {
// mustache 파일에서 {}를 3개 쓰면 <br>과 같은 html 기능을 적용할 수 있다.
result += "채용 공고 = " + titleList.get(i).getText()
+ " "
+ " 회사 = " + companyList.get(i).getText() + "<br>";
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
driver.close();
return result;
}
}
보완할 점
1) 오류 가 발생했다. 이 오류가 정확히 왜 발생했는지는 알 수 없지만 오류가 발생한 상황을 아래에 적어놓으려 한다. 정상적으로 동작한 상황은 위에 제시한 코드다.
알아냈다면 반드시 그 이유를 여기에 남겨놓자.
- 오류 상황
package org.example.springboot.web.recruiteWebSite;
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class SaramIn {
// 파라미터 str = 검색 url
// 일단, 채용정보 1페이지에 있는 내용만 출력하도록 하자.
// 채용정보 파라미터는 recruitPage. company 뒤에 &로 이어서 전달하면 된다.
// ex) 2페이지 - recruitPage = 2
public static String saramInSearch(String str) throws IOException {
String result = "";
WebDriver driver;
final String WEB_DRIVER_ID = "webdriver.chrome.driver";
final String WEB_DRIVER_PATH = "C:/devtool/chromedriver_win32/chromedriver.exe"; // 크롬 드라이버 경로
String base_url; // 크롤링 할 url
// System Property 설정
System.setProperty(WEB_DRIVER_ID, WEB_DRIVER_PATH);
driver = new ChromeDriver();
base_url = str + "&recruitPage="; // 페이지 번호 매개변수를 추가한 url
List<WebElement> titleList = new LinkedList<WebElement>();
List<WebElement> companyList = new LinkedList<WebElement>();
try {
int pageNumber = 1;
int prevCount = 0; // titleList가 이전에 가지고 있던 자료 크기
while(true) {
//get page (= 브라우저에서 url을 주소창에 넣은 후 request 한 것과 같다)
driver.get(base_url + Integer.toString(pageNumber++));
// item_recruit라는 이름의 클래스 리스트를 불러옴
// <div id = "recruit_info_list"> -> <div class = "content">
// -> <div class = "item_recruit"> -> <div class = "area_job"> -> <h2 class = "job_tit">
titleList.addAll(driver.findElements(
By.cssSelector("#recruit_info_list > div.content > div.item_recruit > div.area_job > h2 > a")));
companyList.addAll(driver.findElements(
By.cssSelector("#recruit_info_list > div.content > div.item_recruit > div.area_corp > strong > a")));
// 더 이상 검색결과가 없을 때까지 반복한다.
// 이전 자료 크기와 현재 자료크기가 같다는 건 검색결과가 없다는 뜻
if(prevCount == titleList.size()) break;
prevCount = titleList.size();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
for(int i = 0; i < titleList.size(); i++) {
// System.out.println(el1.get(i).getText());
// {}를 3개 쓰면서 <br>을 추가해줌으로써 줄 바꿈이 가능해짐
// 문제가 된 부분
// stale element reference: element is not attached to the page document
// 진짜 text를 읽을 수 없어서 생긴 문제 - https://heodolf.tistory.com/80 -
result += "채용 공고 = " + titleList.get(i).getText()
+ " "
+ " 회사 = " + companyList.get(i).getText() + "<br>";
}
} catch (Exception e) {
e.printStackTrace();
}
driver.close();
return result;
}
}
위 코드에서 문제가 된 부분
을 아래와 같이 바꾼다면
result += "채용 공고 = " + titleList.get(i).
+ " "
+ " 회사 = " + companyList.get(i). + "<br>";
이런 결과가 나온다.
채용 공고 = [ChromeDriver: chrome on WINDOWS (a4f958a4c6c90b3b9be6163dd75a2f4f)] -> css selector: #recruit_info_list > div.content > div.item_recruit > div.area_job > h2 > a] 회사 = [ChromeDriver: chrome on WINDOWS (a4f958a4c6c90b3b9be6163dd75a2f4f)] -> css selector: #recruit_info_list > div.content > div.item_recruit > div.area_job > strong > a]