[오토핫키] Winhttp 활용하여 뉴스 크롤링하기
2024. 10. 17. 09:16ㆍ오토핫키 오픈 스크립트
Winhttp 활용하여 뉴스 제목 및 기사를 크롤링 하는 스크립트입니다.
공부용으로 살펴보시면 좋습니다.
; WinHTTP 객체 생성
wh := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
; 첫 번째 사이트에서 HTML 소스 가져오기
url1 := "https://www.hankyung.com/economy/0408"
wh.Open("GET", url1)
wh.Send()
htmlSource1 := wh.ResponseText()
; 불필요한 공백 및 줄바꿈 제거
cleanHtml1 := RegExReplace(htmlSource1, "\s+", " ")
; 첫 번째 사이트의 기사 제목 및 링크 추출
articlePattern1 := "<a[^>]*href=""(https://www\.hankyung\.com/article/[^""]*)""[^>]*>(.*?)</a>"
titles1 := []
links1 := []
pos1 := 1
while pos1 := RegExMatch(cleanHtml1, articlePattern1, match1, pos1)
{
titleText1 := RegExReplace(match12, "<img[^>]*>", "")
if (Trim(titleText1) != "")
{
; HTML 엔티티를 실제 문자로 변환
titleText1 := RegExReplace(titleText1, """, """")
titleText1 := RegExReplace(titleText1, "&", "&")
titleText1 := RegExReplace(titleText1, "‘", "‘")
titleText1 := RegExReplace(titleText1, "’", "’")
titleText1 := RegExReplace(titleText1, "“", "“")
titleText1 := RegExReplace(titleText1, "”", "”")
titleText1 := RegExReplace(titleText1, " ", " ")
links1.Push(match11)
titles1.Push(Trim(titleText1))
}
pos1 += StrLen(match1)
}
; 두 번째 사이트에서 HTML 소스 가져오기
url2 := "https://www.ytn.co.kr/news/list.php?mcd=0102"
wh.Open("GET", url2)
wh.Send()
htmlSource2 := wh.ResponseText()
; 불필요한 공백 및 줄바꿈 제거
cleanHtml2 := RegExReplace(htmlSource2, "\s+", " ")
; 두 번째 사이트의 기사 제목 및 링크 추출
articlePattern2 := "<a[^>]*href=""(https://www\.ytn\.co\.kr/_ln/0102_[^""]*)""[^>]*>([^<]*)</a>"
titles2 := []
links2 := []
pos2 := 1
while pos2 := RegExMatch(cleanHtml2, articlePattern2, match2, pos2)
{
titleText2 := Trim(match22)
if (titleText2 != "")
{
; HTML 엔티티를 실제 문자로 변환
titleText2 := RegExReplace(titleText2, """, """")
titleText2 := RegExReplace(titleText2, "&", "&")
titleText2 := RegExReplace(titleText2, "‘", "‘")
titleText2 := RegExReplace(titleText2, "’", "’")
titleText2 := RegExReplace(titleText2, "“", "“")
titleText2 := RegExReplace(titleText2, "”", "”")
titleText2 := RegExReplace(titleText2, " ", " ")
links2.Push(match21)
titles2.Push(titleText2)
}
pos2 += StrLen(match2)
}
; 첫 번째 리스트뷰 추가
Gui, Add, ListView, r10 w600 vListView1 gListViewDoubleClick1, 한국경제
LV_ModifyCol(1, "AutoHdr")
for index, title in titles1
{
LV_Add("", title)
}
; 두 번째 리스트뷰 추가
Gui, Add, ListView, r10 w600 vListView2 gListViewDoubleClick2, YTN 뉴스
LV_ModifyCol(1, "AutoHdr")
for index, title in titles2
{
LV_Add("", title)
}
Gui, Show
Return
; 첫 번째 리스트뷰 기사 본문 추출 함수
ExtractArticleBody1(Source) {
; </figure> 태그 이후부터 .com 이전까지의 텍스트를 추출
RegExMatch(Source, "</figure>(.*?)\.com", match)
ArticleBody := match1
; <br /> 태그를 줄바꿈으로 대체
ArticleBody := RegExReplace(ArticleBody, "<br\s*/?>", "`n")
; HTML 엔티티를 실제 문자로 변환
ArticleBody := RegExReplace(ArticleBody, "‘", "‘")
ArticleBody := RegExReplace(ArticleBody, "’", "’")
ArticleBody := RegExReplace(ArticleBody, "“", "“")
ArticleBody := RegExReplace(ArticleBody, "”", "”")
ArticleBody := RegExReplace(ArticleBody, " ", " ")
ArticleBody := RegExReplace(ArticleBody, """, """")
ArticleBody := RegExReplace(ArticleBody, "&", "&")
ArticleBody := RegExReplace(ArticleBody, "'", "'")
; 앞뒤 공백 제거
ArticleBody := Trim(ArticleBody)
return ArticleBody
}
; 두 번째 리스트뷰 기사 본문 추출 함수
ExtractArticleBody2(Source) {
; <span style로 시작하고 </span>으로 끝나는 텍스트 추출 (s 플래그는 정규 표현식 패턴에 포함)
RegExMatch(Source, "(?s)<span style.*?>(.*?)</span>", match)
ArticleBody := match1
; <br /> 태그를 줄바꿈으로 대체
ArticleBody := RegExReplace(ArticleBody, "<br\s*/?>", "`n")
; HTML 엔티티를 실제 문자로 변환
ArticleBody := RegExReplace(ArticleBody, "‘", "‘")
ArticleBody := RegExReplace(ArticleBody, "’", "’")
ArticleBody := RegExReplace(ArticleBody, "“", "“")
ArticleBody := RegExReplace(ArticleBody, "”", "”")
ArticleBody := RegExReplace(ArticleBody, " ", " ")
ArticleBody := RegExReplace(ArticleBody, """, """")
ArticleBody := RegExReplace(ArticleBody, "&", "&")
ArticleBody := RegExReplace(ArticleBody, "'", "'")
; 앞뒤 공백 제거
ArticleBody := Trim(ArticleBody)
return ArticleBody
}
; 첫 번째 리스트뷰 더블클릭 이벤트 처리
ListViewDoubleClick1:
if (A_GuiEvent = "DoubleClick")
{
LV_GetText(selectedTitle1, A_EventInfo)
selectedLink1 := links1[A_EventInfo]
; 기사 본문 가져오기
wh.Open("GET", selectedLink1)
wh.Send()
articleSource1 := wh.ResponseText()
articleBody1 := ExtractArticleBody1(articleSource1)
; 기사 본문을 보여주는 새 GUI 창 생성
Gui, 2:Destroy ; 이전 GUI가 있으면 파괴
Gui, 2:Add, Text,, % "기사 링크: " selectedLink1
Gui, 2:Add, Edit, r20 w600, % articleBody1
Gui, 2:Add, Button, gOpenLink1, 링크 열기
Gui, 2:Show,, 기사 본문
}
Return
OpenLink1:
{
; 클릭 시 기본 웹 브라우저에서 링크 열기
Run, %selectedLink1%
; 링크 열기 버튼 클릭 후 GUI 창 파괴
Gui, 2:Destroy
}
Return
; 두 번째 리스트뷰 더블클릭 이벤트 처리
ListViewDoubleClick2:
if (A_GuiEvent = "DoubleClick")
{
LV_GetText(selectedTitle2, A_EventInfo)
selectedLink2 := links2[A_EventInfo]
; 기사 본문 가져오기
wh.Open("GET", selectedLink2)
wh.Send()
articleSource2 := wh.ResponseText()
articleBody2 := ExtractArticleBody2(articleSource2)
; 기사 본문을 보여주는 새 GUI 창 생성
Gui, 3:Destroy ; 이전 GUI가 있으면 파괴
Gui, 3:Add, Text,, % "기사 링크: " selectedLink2
Gui, 3:Add, Edit, r20 w600, % articleBody2
Gui, 3:Add, Button, gOpenLink2, 링크 열기
Gui, 3:Show,, 기사 본문
}
Return
OpenLink2:
{
; 클릭 시 기본 웹 브라우저에서 링크 열기
Run, %selectedLink2%
; 링크 열기 버튼 클릭 후 GUI 창 파괴
Gui, 3:Destroy
}
Return
; GUI 닫기 처리
GuiClose:
ExitApp
프로그램 개발 의뢰 및 문의
검은망치 카카오톡오픈프로필 : https://open.kakao.com/o/sDUaoCNg
[오토핫키] 검은망치님의 오픈프로필
오토핫키 개발러
open.kakao.com
'오토핫키 오픈 스크립트' 카테고리의 다른 글
[오토핫키] Gui창에 드래그 앤 드롭(Drag and Drop) 기능 만들기. (0) | 2024.10.01 |
---|---|
[오토핫키] Gui창에 그라데이션 효과 주기. (1) | 2024.10.01 |
[오토핫키] Gui 색상을 랜덤하게 변경 시켜보자. (0) | 2024.10.01 |
[오토핫키] 독립적으로 실행이 불가능한 프로그램 (0) | 2024.09.20 |
[오토핫키] 구글 API를 활용한 실시간 번역 프로그램 (스크립트 공유) (0) | 2024.09.20 |