Reddit 스크래핑은 인기 있는 주제, 커뮤니티 참여도, 인기 게시물에 대한 풍부한 정보를 제공합니다. Reddit의 공식 API는 이러한 콘텐츠에 액세스하기 위한 일반적인 도구이지만, 데이터 선택의 유연성을 높여 스크래핑을 통해 극복할 수 있는 한계가 있습니다. 이 튜토리얼에서는 동적 콘텐츠 관리를 위한 비동기식 Playwright 라이브러리와 데이터 추출을 위한 lxml 라이브러리를 사용하여 Reddit 스크래핑에 포괄적으로 접근할 수 있는 방법을 안내합니다.
시작하기 전에 Python과 필요한 라이브러리가 설치되어 있는지 확인하세요:
pip install playwright
pip install lxml
필요한 라이브러리를 설치한 후 Playwright 브라우저 바이너리를 설치해야 합니다:
playwright install
크롬 브라우저를 설치하려면 다음 명령을 사용하세요:
Playwright install chromium
이러한 도구는 Reddit의 동적 콘텐츠와 상호 작용하고, HTML을 구문 분석하고, 필요한 데이터를 추출하는 데 도움이 됩니다.
Playwright는 브라우저를 제어하고 실제 사용자처럼 웹 페이지와 상호 작용할 수 있는 강력한 도구입니다. 이 도구를 사용하여 Reddit 페이지를 로드하고 HTML 콘텐츠를 가져오겠습니다.
다음은 Reddit 페이지를 로드하는 Playwright 비동기 코드입니다:
import asyncio
from playwright.async_api import async_playwright
async def fetch_page_content():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=False)
context = await browser.new_context()
page = await context.new_page()
await page.goto("https://www.reddit.com/r/technology/top/?t=week")
page_content = await page.content()
await browser.close()
return page_content
# 페이지 콘텐츠 가져오기
page_content = asyncio.run(fetch_page_content())
스크래핑 시 속도 제한이나 IP 차단과 같은 문제가 발생할 수 있습니다. 이러한 문제를 완화하기 위해 프록시를 사용하여 IP 주소와 사용자 정의 헤더를 회전시켜 실제 사용자 행동을 모방할 수 있습니다.
스크래핑할 때 속도 제한이나 IP 차단과 같은 문제가 발생할 수 있습니다. 이러한 문제를 완화하기 위해 프록시를 사용하여 IP 주소와 사용자 정의 헤더를 회전시켜 실제 사용자 행동을 모방할 수 있습니다. 프록시를 사용하여 IP 주소를 순환하고 탐지를 피할 수 있습니다. 이 작업은 서비스 제공업체에서 처리할 수 있으며, 서비스 제공업체가 IP 풀을 관리하고 필요에 따라 로테이션할 수 있습니다.
async def fetch_page_content_with_proxy():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True, proxy={
"server": "http://proxy-server:port",
"username": "your-username",
"password": "your-password"
})
context = await browser.new_context()
page = await context.new_page()
await page.goto("https://www.reddit.com/r/technology/top/?t=week", wait_until='networkidle')
page_content = await page.content()
await browser.close()
return page_content
HTML 콘텐츠가 확보되면 다음 단계는 lxml을 사용하여 콘텐츠를 구문 분석하고 관련 데이터를 추출하는 것입니다.
from lxml import html
# HTML 콘텐츠 구문 분석
parser = html.fromstring(page_content)
Reddit의 r/technology 하위 레딧의 인기 게시물은 문서 요소에 포함되어 있습니다. 이러한 요소는 다음 XPath를 사용하여 타깃팅할 수 있습니다:
# 개별 게시물 요소 추출
elements = parser.xpath('//article[@class="w-full m-0"]')
XPath는 HTML 문서에서 노드를 탐색하고 선택하기 위한 강력한 도구입니다. 각 글에서 제목, 링크, 태그를 추출하는 데 사용하겠습니다.
다음은 각 데이터 요소에 대한 구체적인 XPath입니다:
Title: @aria-label
Link: .//div[@class="relative truncate text-12 xs:text-14 font-semibold mb-xs "]/a/@href
Tag: .//span[@class="bg-tone-4 inline-block truncate max-w-full text-12 font-normal align-text-bottom text-secondary box-border px-[6px] rounded-[20px] leading-4 relative top-[-0.25rem] xs:top-[-2px] my-2xs xs:mb-sm py-0 "]/div/text()
이제 요소를 타깃팅했으므로 각 게시물을 반복하여 필요한 데이터를 추출할 수 있습니다.
posts_data = []
# 각 게시물 요소를 반복합니다.
for element in elements:
title = element.xpath('@aria-label')[0]
link = element.xpath('.//div[@class="relative truncate text-12 xs:text-14 font-semibold mb-xs "]/a/@href')[0]
tag = element.xpath('.//span[@class="bg-tone-4 inline-block truncate max-w-full text-12 font-normal align-text-bottom text-secondary box-border px-[6px] rounded-[20px] leading-4 relative top-[-0.25rem] xs:top-[-2px] my-2xs xs:mb-sm py-0 "]/div/text()')[0].strip()
post_info = {
"title": title,
"link": link,
"tag": tag
}
posts_data.append(post_info)
데이터를 추출한 후에는 데이터를 구조화된 형식으로 저장해야 합니다. JSON은 이러한 목적으로 널리 사용되는 형식입니다.
import json
# 데이터를 JSON 파일에 저장
with open('reddit_posts.json', 'w') as f:
json.dump(posts_data, f, indent=4)
print("Data extraction complete. Saved to reddit_posts.json")
다음은 r/technology에서 Reddit의 인기 게시물을 스크랩하고 데이터를 JSON으로 저장하는 전체 코드입니다:
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json
async def fetch_page_content():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True, proxy={
"server": "IP:port",
"username": "your-username",
"password": "your-password"
})
context = await browser.new_context()
page = await context.new_page()
await page.goto("https://www.reddit.com/r/technology/top/?t=week", wait_until='networkidle')
page_content = await page.content()
await browser.close()
return page_content
# 페이지 콘텐츠 가져오기
page_content = asyncio.run(fetch_page_content())
# lxml을 사용하여 HTML 콘텐츠 구문 분석
parser = html.fromstring(page_content)
# 개별 게시물 요소 추출
elements = parser.xpath('//article[@class="w-full m-0"]')
# 추출된 데이터를 저장할 목록을 초기화합니다.
posts_data = []
# 각 게시물 요소를 반복합니다.
for element in elements:
title = element.xpath('@aria-label')[0]
link = element.xpath('.//div[@class="relative truncate text-12 xs:text-14 font-semibold mb-xs "]/a/@href')[0]
tag = element.xpath('.//span[@class="bg-tone-4 inline-block truncate max-w-full text-12 font-normal align-text-bottom text-secondary box-border px-[6px] rounded-[20px] leading-4 relative top-[-0.25rem] xs:top-[-2px] my-2xs xs:mb-sm py-0 "]/div/text()')[0].strip()
post_info = {
"title": title,
"link": link,
"tag": tag
}
posts_data.append(post_info)
# 데이터를 JSON 파일에 저장
with open('reddit_posts.json', 'w') as f:
json.dump(posts_data, f, indent=4)
print("Data extraction complete. Saved to reddit_posts.json")
이 방법을 사용하면 다양한 하위 레딧을 스크래핑하여 Reddit 커뮤니티 내의 풍부한 토론에서 통찰력 있는 정보를 수집할 수 있습니다. 로테이팅 프록시를 사용하여 Reddit에 의해 탐지될 위험을 최소화하는 것이 중요합니다. 온라인에서 신뢰도가 가장 높은 모바일 및 주거용 동적 프록시를 사용하면 캡차나 차단을 트리거하지 않고 데이터를 수집할 수 있으므로 보다 원활한 스크래핑 환경을 조성할 수 있습니다.
댓글: 0