기존에 작성된 코드의 유지보수를 위해 처음으로 크롤링 코드를 접해봄
진행하며 알게된 것들을 복기 목적으로 정리.
spider, scrapy, scrapy-selenium?
scrapy-selenium(미들웨어)
- 스크래피 요청(Request)을 처리할 때 셀레니움 웹드라이버(필자는 크롬 사용) 런치, url로드, 종료해줌
- 셀레니움을 통해 로드된 HTML을 가져와서 Scrapy의 표준 응답객체와 유사한 SeleniumResponse 객체로 변환하여 스파이더에게 전달.
- JavaScript 실행이 필요한 동적(Dynamic) 웹 페이지도 scrapy-selenium 을 사용하면 Scrapy의 프레임워크 내에서 쉽게 처리
selenium을 별도로 사용할 경우
- 스파이더 내에서 직접 webdriver.Chrome() 등으로 WebDriver를 수동으로 초기화
- 데이터 추출 후에는 driver.quit() 또는 driver.close()를 사용하여 WebDriver를 수동으로 종료
크롤링 작동 플로우
1. 초기화 및 페이지 준비
driver: webdriver.Chrome = response.request.meta['driver']
Scrapy-Selenium 미들웨어를 통해 이미 준비된 Selenium WebDriver 객체를 가져온다.
2. XPATH로 특정 메뉴 버튼을 찾아 클릭하여 페이지 이동
driver.page_source를 반복적으로 확인하여 JavaScript 동작으로 인한 DOM 변경이 멈출 때까지 기다려야 함
3. 스크롤 영역 설정
driver.execute_script('arguments[0].setAttribute("style", "overflow: auto;height: 600px;...")', left_con)
문제
1. 뷰포트 밖 요소 참조문제
Selenium은 화면에 보이지 않는 요소(뷰포트 밖)에 대한 상호작용(클릭)이 불안정하거나 불가능할 수 있음
요소를 화면에 노출시킨 후 클릭
driver.execute_script("arguments[0].scrollIntoView...", _expand_btn)
2. CDATA 처리
XML 출력 시 데이터 내부에 <나 > 기호가 포함되어 XML 문법 오류를 일으킬 가능성이 있다면, 반드시 <![CDATA[...]]]> 섹션으로 감싸야 한다.
이 경우, XML 생성 라이브러리가 자동으로 CDATA 선언을 인코딩하지 않도록 주의.
수정
1. xpath 등으로 페이지 구조 확인
예시 :

xpath -> /html/body/div[1]/section/div/div/div[2]/div/section/section[1]/h2
수집 로직
# 수집
self.total_count += 1
item = ArticleItem()
self.custom_logger.info(f"기사 '{book_id}' 수집 요청 - '{response.url}'")
error_flag = False
item["article_id"] = article_id
item['article_date'] = article_date
try :
article_selector_list = response.xpath("//div[@id='innerbody']/div[not(self::div[@id='a'])]")
articles_list = []
for article in article_selector_list:
collected_article = {}
try :
article_id = article.xpath("./@id").get() # {아이디}
'피드백 & 복습' 카테고리의 다른 글
| 몽고DB 데이터 덤프 (0) | 2025.12.17 |
|---|---|
| pyarmor + pyinstaller (1) | 2025.10.24 |
| miniconda로 가상환경 구축하기 (0) | 2025.09.25 |