최신 뉴스 헤드라인을 수집하고, 뉴스 트렌드를 모니터링하고, 현재 이슈에 대한 감성 분석을 수행할 때 Google 뉴스 스크래핑은 매우 유용한 도구입니다. 이 문서에서는 Python을 사용하여 Google 뉴스를 스크랩하는 과정을 안내합니다. 페이지 콘텐츠를 얻기 위해 요청 라이브러리를 사용하고, HTML 문서를 파싱하고 필요한 데이터를 추출하기 위해 lxml을 사용합니다. 이 튜토리얼이 끝나면 Google 뉴스에서 뉴스 헤드라인과 해당 링크를 구조화된 JSON 형식으로 추출하는 방법을 배우게 됩니다.
시작하기 전에 시스템에 Python이 설치되어 있는지 확인하세요. 다음 명령을 실행하여 필요한 라이브러리를 설치할 수 있습니다:
pip install requests
pip install lxml
이러한 라이브러리를 통해 HTTP 요청을 하고 웹페이지의 HTML 콘텐츠를 구문 분석할 수 있습니다.
다음 URL에서 Google 뉴스 페이지를 스크랩하겠습니다:
URL = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"
이 페이지에는 각각 메인 헤드라인과 관련 기사가 있는 여러 뉴스 항목이 포함되어 있습니다. 이러한 항목의 XPath 구조는 다음과 같습니다:
Google 뉴스의 HTML 구조는 여러 페이지에서 일관성을 유지하여 지정된 XPath 요소가 보편적으로 적용될 수 있도록 합니다.
요청 라이브러리를 사용하여 Google 뉴스 페이지의 콘텐츠를 가져오는 것부터 시작하겠습니다. 다음은 페이지 콘텐츠를 가져오는 코드입니다:
import requests
url = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"
response = requests.get(url)
if response.status_code == 200:
page_content = response.content
else:
print(f"Failed to retrieve the page. Status code: {response.status_code}")
이 코드는 Google 뉴스 URL에 GET 요청을 전송하고 페이지의 HTML 콘텐츠를 page_content 변수에 저장합니다.
HTML 콘텐츠가 준비되면 lxml을 사용하여 페이지를 구문 분석하고 뉴스 헤드라인과 링크를 추출할 수 있습니다.
from lxml import html
# HTML 콘텐츠 구문 분석
parser = html.fromstring(page_content)
Google 뉴스는 특정 컨테이너에 기사를 정리합니다. 먼저 XPath를 사용하여 이러한 컨테이너를 추출한 다음 이를 반복하여 개별 뉴스 헤드라인과 링크를 추출합니다.
주요 뉴스 기사는 다음 XPath 아래에 있습니다:
main_news_elements = parser.xpath('//c-wiz[@jsrenderer="ARwRbe"]')
이제 처음 10개의 유효한 요소를 반복하여 제목과 링크를 추출할 수 있습니다:
news_data = []
for element in main_news_elements[:10]:
title = element.xpath('.//c-wiz/div/article/a/text()')[0]
link = "https://news.google.com" + element.xpath('.//c-wiz/div/article/a/@href')[0][1:]
# 목록에 추가하기 전에 데이터가 있는지 확인합니다.
if title and link:
news_data.append({
"main_title": title,
"main_link": link,
})
메인 뉴스 요소에는 관련 뉴스가 있는 하위 섹션이 있습니다. 비슷한 접근 방식을 사용하여 이러한 하위 섹션을 추출할 수 있습니다:
related_articles = []
related_news_elements = element.xpath('.//c-wiz/div/div/article')
for related_element in related_news_elements:
related_title = related_element.xpath('.//a/text()')[0]
related_link = "https://news.google.com" + related_element.xpath('.//a/@href')[0][1:]
related_articles.append({"title": related_title, "link": related_link})
news_data.append({
"main_title": title,
"main_link": link,
"related_articles": related_articles
})
데이터를 추출한 후 나중에 사용할 수 있도록 JSON 파일에 저장할 수 있습니다.
import json
with open('google_news_data.json', 'w') as f:
json.dump(news_data, f, indent=4)
이 코드는 스크랩한 모든 뉴스 헤드라인과 해당 링크가 포함된 google_news_data.json이라는 파일을 생성합니다.
특히 Google 뉴스와 같이 트래픽이 많은 사이트에서 대량의 데이터를 스크랩할 때 IP 차단이나 속도 제한과 같은 문제가 발생할 수 있습니다. 이를 방지하기 위해 프록시를 사용할 수 있습니다. 프록시를 사용하면 다양한 IP 주소를 통해 요청을 라우팅하여 웹사이트가 스크래핑 활동을 감지하고 차단하기 어렵게 만들 수 있습니다.
이 튜토리얼에서는 requests.get 호출을 수정하여 프록시를 사용할 수 있습니다:
proxies = {
"http": "http://your_proxy_ip:port",
"https": "https://your_proxy_ip:port",
}
response = requests.get(url, proxies=proxies)
프록시 로테이션을 관리하는 서비스 제공업체와 협력하는 경우 요청에서 해당 서비스만 구성하면 됩니다. 서비스 제공업체에서 로테이션 및 IP 풀 관리를 처리합니다.
때때로 웹사이트는 요청이 브라우저에서 온 것임을 식별하는 사용자 에이전트 문자열과 같은 적절한 헤더가 없는 요청을 차단할 수 있습니다. 헤더를 사용자 지정하여 감지를 피할 수 있습니다:
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'cache-control': 'no-cache',
'dnt': '1',
'pragma': 'no-cache',
'priority': 'u=0, i',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'sec-ch-ua-arch': '"x86"',
'sec-ch-ua-bitness': '"64"',
'sec-ch-ua-full-version-list': '"Not)A;Brand";v="99.0.0.0", "Google Chrome";v="127.0.6533.72", "Chromium";v="127.0.6533.72"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-model': '""',
'sec-ch-ua-platform': '"Linux"',
'sec-ch-ua-platform-version': '"6.5.0"',
'sec-ch-ua-wow64': '?0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}
response = requests.get(url, headers=headers)
다음은 모든 단계를 결합한 전체 코드입니다:
import requests
import urllib3
from lxml import html
import json
urllib3.disable_warnings()
# URL 및 헤더
url = "https://news.google.com/topics/CAAqKggKIiRDQkFTRlFvSUwyMHZNRGRqTVhZU0JXVnVMVWRDR2dKSlRpZ0FQAQ?hl=en-US&gl=US&ceid=US%3Aen"
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'accept-language': 'en-IN,en;q=0.9',
'cache-control': 'no-cache',
'dnt': '1',
'pragma': 'no-cache',
'priority': 'u=0, i',
'sec-ch-ua': '"Not)A;Brand";v="99", "Google Chrome";v="127", "Chromium";v="127"',
'sec-ch-ua-arch': '"x86"',
'sec-ch-ua-bitness': '"64"',
'sec-ch-ua-full-version-list': '"Not)A;Brand";v="99.0.0.0", "Google Chrome";v="127.0.6533.72", "Chromium";v="127.0.6533.72"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-model': '""',
'sec-ch-ua-platform': '"Linux"',
'sec-ch-ua-platform-version': '"6.5.0"',
'sec-ch-ua-wow64': '?0',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
}
# 프록시 구성(프록시 세부 정보로 교체)
proxy = 'ip:port'
proxies = {
"http": f"http://{proxy}",
"https": f"https://{proxy}",
}
# 지정된 헤더 및 프록시를 사용하여 페이지 콘텐츠 가져오기
response = requests.get(url, headers=headers, proxies=proxies, verify=False)
# 요청이 성공했는지 확인
if response.status_code == 200:
page_content = response.content
else:
print(f"Failed to retrieve the page. Status code: {response.status_code}")
exit()
# lxml을 사용하여 HTML 콘텐츠 구문 분석
parser = html.fromstring(page_content)
# 주요 뉴스 및 관련 기사 추출
main_news_elements = parser.xpath('//*[@id="i10-panel"]/c-wiz/c-wiz')
# 추출된 뉴스 데이터를 저장할 목록을 초기화합니다.
news_data = []
# 각 주요 뉴스 요소를 반복해서 살펴보기
for element in main_news_elements[:10]:
# 주요 뉴스 제목 및 링크 추출
title = element.xpath('.//c-wiz/div/article/a/text()')
link = element.xpath('.//c-wiz/div/article/a/@href')
# 이 메인 뉴스의 관련 기사를 저장할 목록을 초기화합니다.
related_articles = []
# 동일한 블록 내에서 관련 뉴스 요소 추출
related_news_elements = element.xpath('.//c-wiz/div/div/article')
# 각 관련 뉴스 요소를 반복해서 살펴보고 제목과 링크를 추출합니다.
for related_element in related_news_elements:
related_title = related_element.xpath('.//a/text()')[0]
related_link = "https://news.google.com" + related_element.xpath('.//a/@href')[0][1:]
related_articles.append({"title": related_title, "link": related_link})
# 주요 뉴스 및 관련 기사를 뉴스_데이터 목록에 추가합니다.
if title is not None:
news_data.append({
"main_title": title,
"main_link": f'https://news.google.com{link}',
"related_articles": related_articles
})
else:
continue
# 추출된 데이터를 JSON 파일에 저장합니다.
with open("google_news_data.json", "w") as json_file:
json.dump(news_data, json_file, indent=4)
print('Data extraction complete. Saved to google_news_data.json')
요청 및 lxml 라이브러리와 함께 Python을 사용하여 Google 뉴스를 스크랩하면 뉴스 트렌드를 자세히 분석할 수 있습니다. 프록시를 구현하고 요청 헤더를 구성하는 것은 차단을 방지하고 스크래퍼의 안정성을 유지하는 데 매우 중요합니다. 이러한 목적에 이상적인 프록시에는 빠른 속도와 낮은 핑을 제공하는 IPv4 및 IPv6 데이터센터 프록시, ISP 프록시가 포함됩니다. 또한 동적 주거용 프록시는 우수한 신뢰 요소로 인해 매우 효과적입니다.
댓글: 0