[Node JS] selenium-MySQL연동하기
[Node JS] selenium-MySQL연동하기 — #nodejs #seleniummysql 학습법 이론 학습을 하기 이전, 명심해야할 학습법이 있다. 1.이해가지 않는다고 ...
#nodejs #seleniummysql
학습법 이론
학습을 하기 이전, 명심해야할 학습법이 있다.
1.이해가지 않는다고 뒤돌아가 다시 보지 말 것
2.외우지 말라
=> 자주 봐서 외워짐을 당하라
=> 크롬을 통해 copy and paste하라
- 이해하는게 중요하다
=> 왜 생겨났는지?
=> 왜 사용하는지?
===> 응용이 가능해진다.
selenium으로 크롤링한 데이터 MySQL에 넣기
selenium으로 크롤링하기
이전글에서 selenium을 사용하여 네이버 데이터를 크롤링하는 방법을 배웠습니다. 이번에는 크롤링한 데이터를 MySQL에 데이터베이스에 저장하는 방법을 다뤄보겠습니다.
설계:
네이버 실행 -> 경제란 클릭 -> 뉴스 데이터 수집 -> MySQL에 저장
크롤링할 데이터
크롤링할 데이터는 다음과 같습니다.
네이버 오늘 읽을만한글 - 경제탭에 들어가면 포스트글이 여럿 나옵니다. 광고글을 제외하고 포스트글의 imgUrl, Title, text, author, date를 수집할 예정입니다.
selenium실행하기
node js selenium-webdriver 기초 실행방법은 이전글에서 확인 가능하니 참고하시기 바랍니다. 이번글에서는 중요한 내용만 다뤄보겠습니다.
원하는 데이터만 추출하는 방법
selenium에서는 원하는 데이터만 추출하는 방법이 존재합니다. 바로 findElements()매서드를 사용하면됩니다.
| let urls = await driver.findElement( By.xpath('//\*\[@id="NM\_THEME\_CONTAINER"\]/div\[1\]/div/ul/li\[1\]/a\[1\]/img') ); |
|---|
위는 imgUrl을 찾기위해 By.xpath를 사용하여 원하는 요소를 찾아주었습니다. 네이버는 class이름이 겹치는 경우가 많아 정확한 경로를 찾기위해 xpath를 사용하였습니다. 사용방법은 개발자모드에서 원하는 요소에서 우클릭 후 Xpath복사를 누르시면됩니다.
하나의 imgUrl이 아닌 여러개의 Url이 필요하기 떄문에 각 포스트마다 Xpath경로를 비교해보았습니다.
| //\\[@id="NM\_THEME\_CONTAINER"\]/div\[1\]/div/ul/li\[1\]/a\[1\]/img //\\[@id="NM\_THEME\_CONTAINER"\]/div\[1\]/div/ul/li\[2\]/a\[1\]/img //\*\[@id="NM\_THEME\_CONTAINER"\]/div\[1\]/div/ul/li\[3\]/a\[1\]/img |
|---|
첫번째 이미지, 두번째 이미지, 세번재 이미지의 경로에서는 li\[n\] > a > img의 차이가 있었습니다. 즉 모든 url을 가져오려면 li를 전체배열 경로로 묶어서 가져오면됩니다.
| let urls = await driver.findElements( By.xpath('//\*\[@id="NM\_THEME\_CONTAINER"\]/div\[1\]/div/ul/li/a\[1\]/img') ); |
|---|
li를 전체로 가져왔고 findElements로 변경해주었습니다. findElements매서드는 찾은 요소를 배열로 반환해줍니다.
동일한 방법으로 title,text,author 데이터를 모아줍니다.
모은 urls를 콘솔로 찍어보면 다음과 같은 데이터가 나옵니다. 이는 저희가 원하는 데이터가 아닌 selenium-driver에서 데이터를 어떻게 모으는지 보여줍니다. 우리가 해야할 것은 이 데이터안에 들어있는 src값으로된 데이터를 추출해야합니다.
img URL을 배열로만들기
이제 찾은 urls,titles,texts를 활용하여 원하는 값을 배열로 만들 것입니다.
| let category = "경제"; let rid = \[\]; let newsImg = \[\]; let newsTitles = \[\]; let newsTexts = \[\]; let newsAuthors = \[\]; let newsDates = \[\]; |
|---|
반복문안에 배열함수를 사용하기위해서 빈배열을 만들어줍니다. 반복문을 돌려 원하는 값을 위 배열에 모두 넣어주겠습니다. (카테고리는 모두 경제라 따로 반복문을 돌리지 않습니다)
배열함수 값추가 매서드 : push()
| for (i = 0; i < titles.length; i++) { *//**img src let imgArr = await urls\[i\].getAttribute("src"); await* newsImg.push(imgArr);} |
|---|
반복문을 돌려줍니다. imgArr이라는 변수를 만들어 위에서 찾은 urls의 i번쨰에있는 src속성을 담아주었습니다. 담긴 데이터는 push를 사용하여 newsImg에 넣어주었습니다.
변수가 여러개라 헷갈릴 수 있으니 잘 확인하여 따라오시기 바랍니다.
모든 데이터를 위와 동일한 형태로 넣어줍니다.
MySQL 테이블에 여러 값을 넣는방법
이제 추출한 데이터를 MySQL로 넣어줘야 합니다. node js에서 MySQL을 연동하여 테이블에 여러개의 데이터를 동시에 넣는 방법은 다음과 같습니다.
| const query = "insert into news\_info(tableName) values ?;"; let values = \[ \[ rid\[0\], newsImg\[0\], category, newsTitles\[0\], newsTexts\[0\], newsAuthors\[0\], newsDates\[0\], \], \[ rid\[1\], newsImg\[1\], category, newsTitles\[1\], newsTexts\[1\], newsAuthors\[1\], newsDates\[1\], \], \[ rid\[2\], newsImg\[2\], category, newsTitles\[2\], newsTexts\[2\], newsAuthors\[2\], newsDates\[2\], \], \[ rid\[3\], newsImg\[3\], category, newsTitles\[3\], newsTexts\[3\], newsAuthors\[3\], newsDates\[3\], \], \[ rid\[4\], newsImg\[4\], category, newsTitles\[4\], newsTexts\[4\], newsAuthors\[4\], newsDates\[4\], \], \];//테이블 칼럼수와 일치하게 데이터를 대입시킬 것 const query\_str = con.query(query, \[values\], (error, result) => { if (error) { throw error; } else { console.log(query\_str.sql); *//** SQL Query문 출력* } }); |
|---|
node를 실행시키면 정상적으로 데이터가 들어간 것을 확인할 수 있습니다.




