정적페이지는 js 없는 html 과 같다.
그래서 크롤링 할 때에도 요청 url 에서 받아온 html 그대로 사용해도 괜찮음.
동적 페이지는 JS로 인하여 변경되는 사항이 있는 페이지임
페이지네이션이 되어있는 사이트를 크롤링 하려고 할 때에, axios + cheerio 만 사용해서는 크롤링이 원하는 방향으로 동작하지 않는다.
아래 사진 처럼 html 과 url 모두 151~200 으로 바뀌었지만 크롤링된 return 값은 1~50임
얘네들을 cheerio 만 사용하여 크롤링했기 때문인데, 이처럼 동적으로 작동하는 사이트에서는 추가적으로 라이브 러리를 하나 더 사용해야 한다
이 친구의 장점은 동적페이지에서 클릭 같은 이벤트를 클릭한 다음 나오는 페이지 까지 크롤링 할수 있는 친구이다.
하나의 요청에 걸리는 시간이 2초 정도 걸린다...
(야매로 해서 그런가?)
아무튼 이러한 느려짐을 해결하기 위해 여러가지 방법을 생각했다.
곡 정보가 들어있는 페이지는 정적페이지 이므로 puppeteer 를 사용하지 않으면 1개의 요청마다 1초보다 안걸리는 시간이 걸린다.
하지만 나는 한국인, 더 빠르게 하고 싶다. 방법이 없을까?
예를들어 1~187 개의 곡에 대한 정보를 크롤링하려고 187 개의 요청을 보낸다고 치면,
1~50, 51~100, 101~150, 151~187 이렇게 4분할 하여 각각 요청하는 것이다.
이를 코드로 실현하려면 아래와 같다.
await Promise.all([
메서드(1~50),
메서드(51~100),
메서드(101~150),
메서드(151~187),
])
위와 같은 코드로 크롤링을 하게 된다면
이렇게 병렬적으로 처리가 된다!!
기존에 187번의 요청에 필요한 시간은 대략 60초 정도 걸렸었다.
하지만 이 방법을 채택하니 20초정도 걸렸다. 40초 아낀것!
하지만 이 방법도 문제가 있긴함..
그래서 사람들은 크롤링 할때 아래 상황을 자주 맞이한다고 한다.
요청 보낼때 헤더에 사람이라고 표기해 주기
요청을 쉬면서(슬립) 보내기
차단먹고 울면서 기다렸다가 풀리면 다시 하기..
출처 : https://www.useragentstring.com/
.get(url, {
headers:{
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
})
극한으로 빠르게 하려는 병렬처리는 자제하거나 슬립을 사용하여 최대한 크롤링 속도를 느리게 해야 차단을 안먹는다.
멜론 감사합니다.