본문 바로가기

Project/Gathering

Crawling 구현 2

이전에 생겼던 문제점을 해결해 보려고 한다.

1. DEV 크롤링시 날짜 정보가 

2024.10.07 (월) ~ 2024.11.08 (금) 이런 형식으로 나와 슬라이싱을 진행하였지만, 중간 중간 해당 슬라이싱으로 전처리가 깔끔하게 되지 않는 것을 확인함.

2. linkareer 크롤링시 날짜 데이터가 D-30 이런 식으로 작성되어있음.

3.  linkareer 크롤링시 이미지 데이터가 

data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27250%27%20height=%27250%27/%3e 다음과 같이 이상한 형식으로 나옴.

 

1번 문제 해결

파이썬 re 패키지를 이용하여 날짜값만 슬라이싱해서 저장해보려고한다.

import re

# 날짜 형식 YYYY.MM.DD를 찾는 정규 표현식 패턴
date_pattern = r"\d{4}\.\d{2}\.\d{2}"

dates = re.findall(date_pattern, date)
ex_start = dates[0] if dates else None
ex_end = dates[1] if len(dates) > 1 else None

다음과 같이 날짜 형식에 패턴을 만들고 re.findall을 이용하여 패턴에 맞는 부분을 전부 추출 후, 첫번째는 시작 날짜, 2번째는 끝 날짜로 지정하여 저장하였다.

 

2번 문제 해결

현재 해당 페이지에서 크롤링을 진행하는데 해당 페이지가 아닌 해당 공모전들을 클릭하여

위와 같이 세부 정보를 직접 받아오는 형식으로 코드를 변경해보고자 한다.

기존과 같이 모든 엑티비티 리스트에서

while True:
        try:
            # 모든 항목을 다시 불러오기
            all_items = wait.until(
                EC.presence_of_all_elements_located(
                    (By.CSS_SELECTOR, ".activity-list-card-item-wrapper")
                )
            )

            # 만약 인덱스가 목록을 초과하면 종료
            if index >= len(all_items):
                break

            item = all_items[index]
            try:
                # 각 항목의 링크 클릭
                link_element = item.find_element(By.CSS_SELECTOR, "a.image-link")
                driver.execute_script("arguments[0].click();", link_element)
                time.sleep(1)
                
                # 크롤링할 정보들 코드..
                
                
                # 데이터를 수집한 후 이전 페이지로 돌아감
                driver.back()
                time.sleep(2)  # 페이지 로드 대기

                # 다음 항목으로 이동하기 위해 인덱스 증가
                index += 1

다음과 같이 정보를 크롤링 후, 뒤로 가기를 통해 구현하였다.

 Stale Element Reference 에러

Selenium에서 흔히 발생하는 오류 중 하나로, 웹 페이지의 특정 요소가 더 이상 유효하지 않을 때 발생한다. 이 오류는 페이지의 DOM(Document Object Model)이 변경(페이지의 HTML 구조가 자바스크립트나 서버의 반응 등에 의해 동적으로 업데이트되거나 재구성된다는 것을 의미)된 경우에 발생한다. 웹 페이지가 동적이거나, 페이지 전환, 새로 고침, 또는 JavaScript로 인해 DOM 구조가 변경될 때 주로 발생한다. -> 따라서 이전에 찾았던 엘리멘트들을 다시 찾아줘야 에러를 방지할 수 있음!

 

날짜 데이터의 경우

다음과 같이 start-at 이라는 class명 밑에 span 태크 속에 저장이 되어 있는 것을 확인하였다.

이 때문에 클래스 네임으로 가져오는 것이 어려워 1번 문제를 해결 했듯이, re 모듈로 날짜 데이터 형식과 맞는 데이터를 가져오고자 한다. 

# 날짜 형식 패턴 (예: YYYY.MM.DD)
date_pattern = r"\d{4}\.\d{2}\.\d{2}"

# 모든 <span> 요소 가져오기
spans = item.find_elements(By.TAG_NAME, "span")

# 날짜 초기화
start_date = None
end_date = None

# 각 <span> 요소의 텍스트 확인
for span in spans:
	text = span.text
	# 정규 표현식을 사용하여 날짜 형식과 일치하는지 확인
	if re.match(date_pattern, text):
		if not start_date:
			start_date = text  # 첫 번째로 찾은 날짜는 시작일로 설정
		elif not end_date:
			end_date = text  # 두 번째로 찾은 날짜는 종료일로 설정
			break  # 종료일을 찾으면 반복 중단

다음과 같이 모든 span 태그를 불러와서 날짜 형식에 맞는 데이터를 추출해 가져오는 형식으로 코드를 변경하였다.

 

3번 문제 해결

링커리어 크롤링시, 이미지 데이터가

data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%2720%27%20height=%2720%27/%3e

다음과 같이 비정상적인 형식으로 받아진다.

Selenium을 사용해 이미지를 크롤링할 때 src 속성이 data:image/svg+xml로 되어 있는 경우가 있을때, 이미지가 아직 로드되지 않았거나, 해당 요소가 Lazy Loading으로 설정되어 있어서 실제 URL 대신 기본값이 설정되어 있는 상태일 가능성이 높다.

따라서 그냥 이미지가 로딩될때까지만 기다려 주면 된다!

# 이미지 URL 가져오기 (src가 실제 URL로 설정될 때까지 대기)
img_element = driver.find_element(By.CLASS_NAME, "card-image")
WebDriverWait(driver, 10).until(lambda driver: img_element.get_attribute("src").startswith("http"))
# 이미지 URL을 가져옴
img = img_element.get_attribute("src")

다음과 같이 이미지가 로딩될때까지 기다려 주는 링크를 추가 해주었다.

결과

다음과 같이 날짜, 이미지 등 정보들을 잘 가져오는 것을 볼 수 있다.

 

크롤링 구현은 이로서 마무리한다.

하지만, 크롤링 시간이 약 2분 20초가 걸리는 관계로 처음에 계획했던 사용자가 원하는 시간에 대외활동 정보를 새로고침하는 부분에 대해 고려해볼 필요성이 있어보인다.. (매일 아침 6시에 새로 고침처럼 고정시간에 자동으로 새로 고침 할 수 있도록 하도록)

이후에는 일단 계획대로 FastAPI를 이용하여 해당 크롤링 코드를 API화 해야겠다.

 

모든 코드는 

https://github.com/software-gathering/gather-be2

 

GitHub - software-gathering/gather-be2

Contribute to software-gathering/gather-be2 development by creating an account on GitHub.

github.com

여기서 확인이 가능하다.

728x90

'Project > Gathering' 카테고리의 다른 글

Gathering 기획 3  (1) 2024.11.21
Gathering 기획 2  (0) 2024.11.16
Crawling 서버 구현  (1) 2024.11.12
Crawling 구현 1  (1) 2024.11.08
Gathering 기획  (0) 2024.11.07