0

아래의 다음 VBA 코드를 사용하여 카운티, 인구 및 중간 값을 웹 스크 레이 핑하려고했습니다. 이 문제가 발생하지만 다음과 같은 문제가 발생합니다. 아래의 블록 따옴표에있는 항목 번호가 다양합니다. 즉, 특정 우편 번호에 대해 잘못된 데이터 요소를 검색합니다 (아래 스프레드 시트 이미지 참조).Excel VBA 웹 스크랩 - getElementsbyTagName.Item 번호가 일정하지 않음

enter image description here

나는 변수 항목 번호를 연구했지만, 가깝게 유일한 경우는 클래스 이름으로 요소를 골라하는 collection를 검색합니다. 그러나, 나는 클래스 이름을 가지고 있지 않습니다와 함께 일하고 있어요 HTML은 아래를 참조하십시오 : 다음 검색 TAGNAMEinnerText와 :

이 가능 처음 문자열 "군"을 찾을 수 있습니다 td? 또한 전체 테이블 반환을 고려했지만 데이터는 서로 다른 두 테이블 내에서 호스팅됩니다. 보시다시피, 몇 가지 아이디어가 있지만 좋은 예제를 찾을 수없는 것 같아서 코드면에서 다소 분실했습니다.

enter image description here

Sub ZipCodeScrape() 

Set ZipCodeRange = Range("C2", Range("C2").End(xlDown)) 

Dim IE As Object 
Set IE = New InternetExplorer 

Dim url As String 
url = "https://www.unitedstateszipcodes.org/" 

Dim County As String 
Dim Population As String 
Dim MedianHomeVal As String 
Dim HTMLdoc As HTMLDocument 

For Each cell In ZipCodeRange 

    IE.navigate (url & cell.Value) 

    'Allows IE to load 
    While IE.readyState <> 4 
     DoEvents 
    Wend 

    Set HTMLdoc = IE.document 

    County = HTMLdoc.getElementsByTagName("td").Item(2).innerText 
    Population = HTMLdoc.getElementsByTagName("td").Item(6).innerText 
    MedianHomeVal = HTMLdoc.getElementsByTagName("td").Item(12).innerText 

    cell.Offset(0, 1) = County 
    cell.Offset(0, 2) = Population 
    cell.Offset(0, 3) = MedianHomeVal 

Next cell 

End Sub 
+1

데이터 쿼리를 사용하여 페이지를 빈 시트로 가져온 다음 셀 참조를 사용하여 데이터에 액세스합니다. 'Alt + D, D, W'. – ACatInLove

답변

1

시도해보십시오. 예상되는 산출물 (카운티, 인구 및 집값의 중앙값)을 가져옵니다. 내가 업로드 한 이미지에서 가져온 검색 옵션을 거의 설정하지 않았습니다. Btw, 우편 번호로 검색해야합니다. 그렇지 않으면 populationmedian home value이 해당 웹 페이지에 표시되지 않습니다.

Sub ZipCodeScrape() 
    Dim IE As New InternetExplorer, html As HTMLDocument 
    Dim search_input As Variant, posts As Object, post As Object, elem As Object 

    With IE 
     .Visible = True 
     .navigate "https://www.unitedstateszipcodes.org/" 
     Do Until .readyState = READYSTATE_COMPLETE: Loop 
     Set html = .document 
    End With 

    Application.Wait Now + TimeValue("00:00:03") 

    For Each search_input In [{"32937","33056","33312","33844","34698"}] 

     html.getElementById("q").Value = search_input 
     html.getElementsByClassName("btn btn-danger")(0).Click 
     Application.Wait Now + TimeValue("00:00:05") 

     For Each posts In html.getElementsByTagName("th") 
      If InStr(posts.innerText, "County:") > 0 Then Row = Row + 1: Cells(Row, 1) = posts.NextSibling.innerText: Exit For 
     Next posts 
     For Each post In html.getElementsByTagName("th") 
      If InStr(post.innerText, "Population") > 0 Then Cells(Row, 2) = post.ParentNode.getElementsByTagName("td")(0).innerText: Exit For 
     Next post 
     For Each elem In html.getElementsByTagName("th") 
      If InStr(elem.innerText, "Median Home Value") > 0 Then Cells(Row, 3) = elem.ParentNode.getElementsByTagName("td")(0).innerText: Exit For 
     Next elem 
    Next search_input 
    IE.Quit 
End Sub 
+0

답변 해 주셔서 감사합니다. 각 게시물에 대해 HTML.getElementsByTagName ("th") InStr (post.innerText, "County :")> 0 Then 카운티 = post.NextSibling.innerText If InStr (post.innerText, "Population")> 0 Then 채우기 = post.NextSibling.innerText InStr (post.innerText, "Median Home Value")> 0 Then MedianHomeVal = post.NextSibling.innerText : 끝내기 For 다음 게시물 –

+0

인구를 발견하면 438 오류가 발생합니다. 나는 그것을 오랫동안 선언하고 NextSibling.Value를 검색하려고 시도했지만 작동하지 않았다. NextSibling.NodeValue가 작동하지 않습니다. 이 다른 사용자는이 SO 스레드에서 동일한 문제를 겪고 있습니다. https://stackoverflow.com/questions/21688478/how-to-read-a-ie-table-text-with-vba (해답에 대한 설명 참조) . 그는 대답을 얻지 못했습니다. 이견있는 사람? –

+0

귀하의 요구 사항은 카운티를 경계표로 삼아 가치를 얻는 것이 었습니다. 그걸 안듣니? 구체적으로 말하십시오. – SIM

2

아마 <th> 요소를 통해 루프 다음 ​​원하는 TD 노드이어야 next sibling 노드보기? 나는 이것을 시험하지 않았다.

For each header in HTMLdoc.getElementsByTagName("th") 
    If header.InnerText = "County: " then 
     county = header.NextSibling.InnerText 
     Exit For 
    End If 
Next 
+0

이 접근법의 유일한 문제점은 "County :"대신 "County", "County :"등이 검색되면 비참하게 실패한다는 것입니다. 즉, 검색 문자열과 웹에있는 문자열이 정확히 일치 할 때만 작동합니다. 사실 선두 또는 끝 공간의 변형은 코드를 깨뜨릴 것입니다. – SIM