아빠는 개발자

[Aqqle] crawler - 쇼핑 본문

Aqqle/Infra structure

[Aqqle] crawler - 쇼핑

father6019 2023. 9. 2. 19:04
728x90
반응형

쇼핑 데이터 크롤러를 만들어야겠다.

크롤링 데이터중에 일부를 dense vector 타입으로 변환 후 테이블에 넣는 것 까지의 롤을 가져가는 시스템

 

우선 크롤링에 필요한 라이브러리의 의존성의부여 받는다. 

dependencies {
    implementation project(':common')
    runtimeOnly 'com.h2database:h2'
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'

    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.0'
    // https://mvnrepository.com/artifact/info.picocli/picocli-spring-boot-starter
    implementation group: 'info.picocli', name: 'picocli-spring-boot-starter', version: '4.6.3'
    runtimeOnly 'mysql:mysql-connector-java'

    // https://mvnrepository.com/artifact/org.jsoup/jsoup
    implementation 'org.jsoup:jsoup:1.16.1'
}

type 파리미터의 T 는 텍스트 만 크롤링, I 는 이미지 크롤링  하지만 그.. 사이트가 이미지를 크롤링 못하게 막아놔서 페이지 로드 후에

긁어도 정상으로 잘 안긁히는..  그거때매 쇼핑몰 프로젝트가 망.. 하게 되었지만 

아무튼 T 타입으로 텍스트 만 긁어 보자

 

비동기 멀티쓰레드로 조질까 하다가.. 지금도 쉬는텀있는 상태로 돌려도.. 막히는거 같으니.. 보류 

@Override
public Integer call() throws Exception {
    switch (type) {
        case "T":
            goodsService.getData(type);
            break;
        case "I":
            crawlerSeleniumService.getData(type);
            break;
        default:
    }
    return ExitCode.OK;
}

데이터를 긁어 오면서 text 를 백터로 바꿔주고 DB 저장 

@Timer
public void getData(String type) {

    Site site = new SiteFactory().getSite(new NaverFactory());
    List<Keywords> keywords = keywordsService.getData();
    keywords.stream().forEach(obj -> {
                try {
                    int i = 0;
                    while (true) {
                        Thread.sleep(2000); //1초 대기
                        String listUrl = site.getUrl(obj.getKeyword(), i);
                        System.out.println(listUrl);
                        Document listDocument = Jsoup.connect(listUrl)
                                .timeout(9000)
                                .get();

                        Elements list = listDocument.select("div.adProduct_inner__W_nuz");
                        list.stream().forEach(element -> {
                            try {
                                Elements title = element.select("div.adProduct_title__amInq>a");
                                Elements price = element.select("strong.adProduct_price__9gODs>span>span.price_num__S2p_v");
                                Elements category = element.select("div.adProduct_depth__s_IUT span");
                                List<String> categoryLists = category.stream().map(x -> x.text()).collect(Collectors.toList());

                                Elements image = element.select("a.thumbnail_thumb__Bxb6Z > img");

                                System.out.println(image.attr("src"));

                                Thread.sleep(1000);

                                goodsRepository.save(GoodsText.builder()
                                        .keyword(obj.getKeyword())
                                        .name(title.text())
                                        .price(price.text().equals("") ? 0 : Integer.parseInt(price.text().replaceAll("[^0-9]", "")))
                                        .category(category.text())
                                        .category1(StringUtils.isEmpty(categoryLists.get(0)) ? "" : categoryLists.get(0))
                                        .category2(StringUtils.isEmpty(categoryLists.get(1)) ? "" : categoryLists.get(1))
                                        .category3(StringUtils.isEmpty(categoryLists.get(2)) ? "" : categoryLists.get(2))
                                        .category4(categoryLists.size() < 4 ? "" : categoryLists.get(3))
                                        .category5(categoryLists.size() < 5 ? "" : categoryLists.get(4))
                                        .image(image.attr("src"))
                                        .featureVector(TextEmbedding.getVector(TextEmbeddingDTO.builder().tensorApiUrl(HostUrl.EMBEDDING.getUrl()).keyword(title.text()).build()).toString())
                                        .popular(1)
                                        .weight(0.1f)
                                        .type("C")
                                        .createdTime(LocalDateTime.now())
                                        .updatedTime(LocalDateTime.now())
                                        .build()
                                );

                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        });
                        if (i > CRAWLING_LIMIT) {
                            break;
                        }
                        i++;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException i) {
                    i.printStackTrace();
                }
                keywordsService.putData(obj);
            }
    );
}

저장된 데이터를 확인 하면.. 아래와 같고..

일단 데이터는 수집까지 완료 

 

추가작업

1. 유실되는 데이터 확인

2. 리스트를 다 가져오는것인지 확인.. (저장속도가 느리다.. )

 

728x90
반응형

'Aqqle > Infra structure' 카테고리의 다른 글

[Aqqle] Database  (0) 2023.09.02