Notice
Recent Posts
Recent Comments
rand(life)
[VBA]웹 스크랩핑 본문
아직 배우는 중
미천한 HTML 지식과 검색으로 웹 스크래핑을 공부하고 있다
아래는 검색해서 얻은 코드. 주석을 붙여보았다.
일단 참조에서 아래와 같이 추가해야한다
대부분 위의 4개는 이미 추가가 되어있을테고, 아래의 2개만 추가하면 된다(엑셀 365기준)
MICROSOFT WinHTTP Services
MICROSOFT HTML Object Library
원 글에서는 네이버 뉴스도 가져오는 코드가 있지만, 그동안 네이버 뉴스가 개편을 한 탓인지 제대로 작동을 안해서 다음 뉴스만 가져오도록 했다.
가능한 주석을 달아보았는데, 아직 공부할 것이 많다.
.getElementById 하고
getElementsByTagName 의 사용법이 아직 완전하지 않다.
<id ~~> 이렇게 되어있는 곳을 가져오는 것 같은데, 테스트삼아 다른 사이트에서 해봤더니 잘 안된다. HTML공부를 좀 더 해야 가능할 듯
Option Explicit
Function request(url As String)
Dim whttp As Object
Set whttp = CreateObject("WinHttp.WinHttpRequest.5.1")
whttp.Open "GET", url
whttp.SetRequestHeader "user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36"
whttp.Send
whttp.WaitForResponse
request = whttp.ResponseText
End Function
Sub insertSht(args() As String) '배열 변수를 받아서 차곡 차곡 정리한다!
With Sheets(args(0)).Range("a1000000").End(xlUp)
.Offset(1, 0) = args(1) '사이트 분류
.Offset(1, 1) = args(2) '제목
.Offset(1, 2) = args(3) '기사 정보
.Offset(1, 3) = args(4) '본문 일부
.Offset(1, 4) = args(5) '본문 링크
End With
End Sub
Sub daumParser(response As String)
Dim doc As Object
Dim elements As IHTMLElementCollection
Dim element As IHTMLElement
Dim args(5) As String
Dim elIdx As Integer
Set doc = New HTMLDocument
'doc도 하나의 HTML문서임
doc.body.innerHTML = response
'위에서 받은 전체내용을 doc의 <body> </body> 사이의 innerHtMl값으로 넣음
doc.body.innerHTML = doc.getElementById("newsResultUL").innerHTML
'받은 전체 html 중에서 newsResultUL이라는 id 아래의 html을 doc의 <body> </body> 사이의 innerHtMl값으로 다시 수정
Set elements = doc.getElementsByTagName("li")
'<li> 태그아래의 요소들 컬렉션 정의
For Each element In elements '컬렉션 내의 각 항목에 대해
'뒤에 img가 있는 기사와 없는 기사의 본문 배열 순서가 다르므로
If element.getElementsByTagName("img").Length > 0 Then
elIdx = 2
Else
elIdx = 1
End If
args(0) = "sheet1"
args(1) = "Daum"
'li 태그 아래에 div 태그 중 2번째(1) 또는 3번째에 있는 <a> 태그 중 첫번째 a 태그안의 텍스트
args(2) = element.getElementsByTagName("div")(elIdx).getElementsByTagName("a")(0).innerText
'li 태그 아래에 div 태그 중 2번째(1) 또는 3번째에 있는 <span> 태그 중 첫번째 span태그 안의 텍스트
args(3) = element.getElementsByTagName("div")(elIdx).getElementsByTagName("span")(0).innerText
args(4) = element.getElementsByTagName("div")(elIdx).getElementsByTagName("p")(0).innerText
'a 태그 안의 접속 주소
args(5) = element.getElementsByTagName("div")(elIdx).getElementsByTagName("a")(0).href
Call insertSht(args)
Next
End Sub
Sub main() '뉴스 수집 모듈 제어
Dim naverNewsHeadUrl, naverNewsTailUrl As String
Dim daumNewsHeadUrl, daumNewsTailUrl As String
Dim keyword, requestUrl As String
Dim page As Integer
keyword = "코로나"
Sheets("sheet1").Range("A:E").Delete
With Sheets("sheet1").Range("a1")
.Offset(0, 0) = "사이트"
.Offset(0, 1) = "제목"
.Offset(0, 2) = "기사 정보"
.Offset(0, 3) = "본문 일부"
.Offset(0, 4) = "본문 주소"
End With
daumNewsHeadUrl = "https://search.daum.net/search?w=news&sort=recency&q="
daumNewsTailUrl = "&cluster=n&DA=PGD&dc=STC&pg=1&r=1&rc=1&at=more&p="
For page = 1 To 10 '페이지까지 반복하며 내용을 가져온다!
Debug.Print ("request Page Number : " & page)
requestUrl = daumNewsHeadUrl & keyword & daumNewsTailUrl & page '다음 기사 요청
daumParser (request(requestUrl)) '다음 요청 결과 파싱
Application.Wait (Now + TimeSerial(0, 0, 1))
Next
End Sub