0

私は、以下のVBAコードを使用して郡、母集団、および中央値をWebスクレープしようとしました。これは動作しますが、次の問題が発生しています:以下のブロック引用符で囲まれた項目番号が異なります。つまり、特定の郵便番号では、誤ったデータポイントを取得します。Excel VBA Web Scrape - getElementsbyTagName.Item番号は一定ではありません

enter image description here

私は、可変項目番号について調査しましたが、近づくだけの場合は、クラス名で要素を拾い出し、collectionを取得しています。しかし、私が働いているHTMLは以下を参照してください、クラス名を持っていない:「郡:」

は、それが最初文字列を見つけることは可能ですし、その後のinnerTextを取得TagNameはtd?また、テーブル全体を返すことも考えましたが、データは2つの異なるテーブル内でホストされています。ご覧のとおり、私はいくつかのアイデアを持っていますが、良い例が見つからないようですので、コードの面では分かりません。

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の場合は、郵便番号で検索する必要があります。そうでない場合は​​とmedian home valueがそのWebページに表示されません。

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 County = post.NextSibling.innerText If InStr投稿者:post.innerText、 "Population")> 0 Then Population = post.NextSibling.innerText InStr(post.innerText、 "Median Home Value")> 0 Then MedianHomeVal = post.NextSibling.innerText:終了次の投稿 –

+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

このアプローチの唯一の問題は、検索が "郡"、 "郡:"などの代わりに "郡:"である場合、それは悲惨に失敗します。つまり、検索文字列とウェブ上の検索文字列がまったく同じ場合にのみ動作します。実際には先頭または末尾のスペースのバリエーションがコードを壊します。 – SIM

関連する問題