해결된 질문
작성
·
581
·
수정됨
0
퍼펫티어 쪽 코드인데 미니프로젝트에서 요구한 30개 이상을 크롤링 하는 부분을 완성을 해서 추가적으로 전체 메뉴를 긁어오고 싶어서 위와 같이 코드를 추가했습니다.
12번째 코드부터 15번째 코드까지가 총 데이터 길이를 구하는 코드인데
해당 코드에서
console.log(cnt);
콘솔로 cnt를 출력해보면
위와 같이 숫자 10까지 밖에 출력이 안되어서 질문 드립니다.
퍼펫티어 docs에서도
이렇게 설명이 되어있어서 해당 코드라면 스타벅스 내에 있는 모든 전체상품 이미지가 크롤링 되어야 될 거 같은데
스타벅스 홈페이지에서 카피를 하면 nth-child 의 값은 10까지 밖에 찍히지 않고
전체 메뉴가 크롤링 되는 것이 아닌 도중에 제주 말차 메뉴까지 밖에 크롤링이 되지 않는 것이 의문이라 질문 드립니다.
혹시 해당 코드에 문제가 무엇인지 조언을 부탁 드리고 싶습니다 ㅠㅠ
전체 코드는 아래와 같습니다.
import puppeteer from "puppeteer"; import mongoose from "mongoose"; import { starbucks } from "../model/starbucksSchema.js"; export async function startCrawling() { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.setViewport({ width: 1920, height: 1080 }); await page.goto("https://www.starbucks.co.kr/menu/drink_list.do"); await page.waitForTimeout(2400); const cnt = await page.$$eval( `#container > div.content > div.product_result_wrap.product_result_wrap01 > div > dl > dd:nth-child(2) > div.product_list > dl > dd `, (data) => data.length ); console.log(cnt); for (let i = 1; i <= cnt; i++) { const second_cnt = await page.$$eval( `#container > div.content > div.product_result_wrap.product_result_wrap01 > div > dl > dd:nth-child(2) > div.product_list > dl > dd:nth-child(${i}) > ul > li`, (data) => data.length ); for (let j = 1; j <= second_cnt; j++) { const image = await page.$eval( `#container > div.content > div.product_result_wrap.product_result_wrap01 > div > dl > dd:nth-child(2) > div.product_list > dl > dd:nth-child(${i}) > ul > li:nth-child(${j}) > dl > dt > a > img`, (el) => el.src ); const name = await page.$eval( `#container > div.content > div.product_result_wrap.product_result_wrap01 > div > dl > dd:nth-child(2) > div.product_list > dl > dd:nth-child(${i}) > ul > li:nth-child(${j}) > dl > dd`, (el) => el.textContent ); console.log(`이름: ${name}, 이미지: ${image}`); const starbucks_db = await starbucks.updateOne( { name: name }, { img: image }, { upsert: true } ); } } await browser.close(); } startCrawling();
답변 2
1
안녕하세요! aegis0918님!
과제를 다 완성하시고, 추가로 프로젝트를 확장하시는 모습! 정말 빠르게 성장하실 것 같아요!
해당 코드에서의 Copy-Selector가 무엇을 가리키는지 확인을 해 보아야 할 것 같아요!
위 제시해주신 코드에서의 Copy-Selector는 아래의 dd:child 들을 모두 선택해 오는 것 같아요!
따라서, 아래의 주제를 모두 세어 보면, 총 10개가 맞는 것 같아요!
따라서, Copy-Selector를 적절히 변경하여서 크롤링을 시도해 보시면 좋을 것 같아요!
1
안녕하세요, 인프런 AI 인턴이에요.
해당 코드상으로는 이상이 없어보입니다. 그러나, 문제가 발생하는 이유는 페이지가 로드되기 전에 데이터 길이를 가져오고 있기 때문일 수도 있습니다. 페이지가 로드되지 않은 상태에서 코드가 실행될 경우, 원하는 값이 출력되지 않을 수 있습니다.
따라서, page.waitForTimeout()
를 이용하여 충분한 시간을 두고 데이터를 긁어오는 것을 추천드립니다. 예를 들어, page.waitForTimeout(5000);
와 같이 5초 동안 기다리도록 설정하면 로드되는 시간을 충분히 고려할 수 있을 것 같습니다.
참고하시길 바랍니다. 감사합니다.
먼저 답변 감사합니다.
말씀해주신 솔루션에 대해서는 저도 시도해 보았습니다.
그 부분을 고려해서 10초 정도까지도 해보았지만 같은 결과가 반복이 되어서요 ㅠㅡㅠ;;
설마... 그럴 일은 없겠지만 정말 만약에 혹시나 스타벅스 홈페이지 쪽에서 문제가 있어서
전체메뉴를 크롤링 해오지 못하는 경우도 있을까요??
답변 감사합니다
해결한 문제였는데 미해결로 남겨두어서 번거롭게 만들어 드린 거 같네요 ㅎㅎ;;;;;
제가 해결한 방법은 선생님께서 말씀해주신 copy-selector를 바꾼 건 아니었지만 child의 숫자가 2의 배수로 커지는 걸 확인해서
첫번째 for문 조건에 cnt*2를 곱하여주니 모두 크롤링이 되었습니다.ㅎㅎ
하지만 뭔가 주먹구구식 해결법인것 같아 말씀해주신 해결방법도 고민하겠습니다.
감사합니다 ^^