(Selenium 사용) 메인메이지 -> 링크 리스트 -> 상세데이터 수집 (페이징 데이터수집)
1. 코드 기능 간략 설명
아래 코드는 Selenium을 사용하여
특정 웹 페이지에 있는 상세 링크릴 클릭하며 상세 페이지 내에 데이터를 자동으로 수집하는 코드다.
페이지네이션을 통해 모든 페이지를 순회하며, 각 페이지에서 원하는 데이터를 추출하고 파일에 저장했다.
이와 같은 방법을 사용하면 대량의 데이터를 자동으로 수집할 수 있어 매우 유용하다.
특정 신문사에 있는 특정 칼럼만 모아서 한꺼번에 보고 싶어서 만들어 봤다.
2. 필요 도구
- Python
- Selenium 라이브러리
- ChromeDriver
3. 설치
먼저, Selenium과 ChromeDriver를 설치해야 한다..
ChromeDriver 는 내 블로그 아래 포스트 참고.
https://betterwe.tistory.com/150
4. 코드 설명
4.1. 드라이버 설정 및 실행
먼저 ChromeDriver 경로를 설정하고, Selenium을 사용하여 웹 드라이버를 실행
from selenium import webdriver
from seleniuhttp://m.webdriver.chrome.service import Service
from seleniuhttp://m.webdriver.common.by import By
import time
# Chrome 웹 드라이버 경로 설정
driver_path = r'C:\path\to\chromedriver.exe' # 예: 'C:/path/to/chromedriver.exe'
main_page_url = '링크리스트가 있는 메인 페이지'
base_url = '메인 페이지의 홈주소, 내 경우 신문사 주소였다'
# ChromeService 객체 생성
service = Service(executable_path=driver_path)
# Chrome 웹 드라이버 실행
options = webdriver.ChromeOptions()
options.add_argument('--headless') # Headless 모드로 실행하여 UI를 표시하지 않음
driver = webdriver.Chrome(service=service, options=options)
4.2. 페이지에서 링크 추출
메인 페이지에서 모든 링크를 추출
def get_links_from_page():
# 페이지 로딩 대기 (필요에 따라 조정)
time.sleep(5)
# 메인 페이지에서 모든 링크 가져오기. 여기서 a 태그의 패턴을 파악해야 한다. 특정 클래스이름으로 가져올 수 있는지. 감싸고 있는 div를 찾을 수 있는지 등...
# 나의 경우 a 태그가 내가 찾는 것 외에도 많이 있어서 내가 찾는 a 태그의 링크 패턴을 분석해서 그 링크가 포함된 것들만 가져왔다.
links = driver.find_elements(By.CSS_SELECTOR, 'a[href*="공통적으로 들어가는 주소"]')
# 링크 URL 중복 제거
unique_links = set(link.get_attribute('href').split('?')[0] for link in links if link.get_attribute('href'))
return unique_links
4.3. 링크 페이지에서 내용 추출
각 링크 페이지로 이동하여 <p> 태그의 내용을 추출. 여기서도 자신이 추출하려는 contents의 태그를 파악, 그 클래스의 패턴도 파악하면 좋다. 나의 경우 맨 처음엔 클래스와 태그까지 명확히 명시했지만 동적페이지라서 그런지 잘 찾아지지 않아 무조건 p태그 들만 찾아 그 안에 컨텐츠를 가져왔다.
def extract_content(link):
try:
driver.get(link)
time.sleep(5) # 페이지 로딩 대기 (필요에 따라 조정)
data_elements = driver.find_elements(By.TAG_NAME, 'p')
content = ' '.join(element.text for element in data_elements)
if content:
print(f"Link click: Success, Content extraction: Success")
print(f"Extracted Content: {content[:200]}...") # Print first 200 characters for verification
return content
else:
print("Link click: Success, Content extraction: No content found")
return None
except Exception as e:
print(f"Link click: Failed ({str(e)})")
return None
4.4. 페이지네이션 처리
여러 페이지에 걸쳐 데이터를 수집하기 위해 페이지네이션을 처리
def main():
driver.get(main_page_url)
all_links = set()
page_count = 0 # Page counter
# Loop through pagination
while True:
page_count += 1
print(f"Crawling page: {page_count}")
# Get links from current page
links = get_links_from_page()
all_links.update(links)
# Try to click the "next" button
try:
next_button = driver.find_element(By.CSS_SELECTOR, 'div.next')
if 'disabled' in next_button.get_attribute('class'):
break
next_button.click()
time.sleep(5) # 페이지 로딩 대기 (필요에 따라 조정)
except Exception as e:
print(f"Pagination failed: {str(e)}")
break
print(f"Total pages crawled: {page_count}")
print(f"Total unique links found: {len(all_links)}")
with open('output.txt', 'w', encoding='utf-8') as file:
for link_url in all_links:
if not link_url.startswith('http'):
full_link_url = base_url + link_url.lstrip('/')
else:
full_link_url = link_url
print(f'Navigating to: {full_link_url}')
# 구분 표시 추가
file.write(f'*****================= Navigating to: {full_link_url} *****\n')
content = extract_content(full_link_url)
if content:
file.write(content + '\n')
driver.quit()
if __name__ == "__main__":
main()