【问题标题】:Extract email HTML Element提取电子邮件 HTML 元素
【发布时间】:2020-04-01 22:06:29
【问题描述】:

我正在尝试抓取一个页面,但我遇到了一个问题。这里首先是整个 HTML 页面的 HTML 部分

<article class="mod mod-Treffer" data-teilnehmerid="122085958708">
			
			<div data-wipe="{&quot;listener&quot;: &quot;click&quot;, &quot;name&quot;: &quot;Trefferliste Eintrag zur Detailseite&quot;, &quot;id&quot;: &quot;122085958708&quot;, &quot;synchron&quot;: true}" data-realid="2aeca1d2-2bc5-4070-ac4d-e16b10badca5" data-tnid="122085958708" target="_self">
				
		<div class="mod-hervorhebung">
	<p class="mod-hervorhebung--partnerHervorhebung" data-hervorhebungsstufe="3">Silber Partner</p>

	

	
</div>
		
			<picture class="trefferlisten_logo">
		<source media="(min-width: 768px)" srcset="https://ies.v4all.de/0122/GS/0122/5/8335/49428335_310x190.png">
		
		<img alt="" data-lazy-src="https://ies.v4all.de/0122/GS/0122/5/8335/49428335_310x190.png" src="https://ies.v4all.de/0122/GS/0122/5/8335/49428335_310x190.png">
	</picture>
		
		<h2 data-wipe-name="Titel">A &amp; S Billing Pflege-Service GmbH</h2>
		<p class="d-inline-block mod-Treffer--besteBranche">Ambulante Pflegedienste</p>
		
			
			<div class="mod mod-Stars mod-Stars--" title="2.9/5" data-float="2,9">

		<span class="mod-Stars__text" style="width: 58.000001907348632812500%;">2.9</span>

	</div>
			<span>2.9</span>
			<span>(8)</span>
		
	
		
		<address class="mod mod-AdresseKompakt">
		<p data-wipe-name="Adresse">
			Kirchenberg&nbsp;2‑4, 
			<span class="nobr">
				90482
				Nürnberg
			</span>
			(Mögeldorf)
			
		</p>

		<p class="mod-AdresseKompakt__phoneNumber" data-hochgestellt-position="end" data-wipe-name="Kontaktdaten">(0911) 60 00 99 77</p>

	</address>
		
	
			</div>
			
				<div class="aktionsleiste_kompakt">
		
	<div class="mod-gsSlider mod-gsSlider--noneOnWhite">
		<span class="mod-gsSlider__arrow mod-gsSlider__arrow--arrow" data-direction="left" data-show="false" data-wipe="{&quot;listener&quot;:&quot;click&quot;,&quot;name&quot;:&quot;Trefferliste: Aktionleiste-button-links&quot;}"></span>
		<span class="mod-gsSlider__arrow mod-gsSlider__arrow--arrow" data-direction="right" data-show="false" data-wipe="{&quot;listener&quot;:&quot;click&quot;,&quot;name&quot;:&quot;Trefferliste: Aktionleiste-button-rechts&quot;}"></span>
		<div class="mod-gsSlider__slider" data-initialized="true">
			
			
			
			
			
			
				
		
			<a class="contains-icon-homepage gs-btn" target="_blank" rel=" noopener" href="http://www.as-billing.de" data-wipe="{&quot;listener&quot;:&quot;click&quot;, &quot;name&quot;:&quot;Trefferliste Webseite-Button&quot;, &quot;id&quot;:&quot;122085958708&quot;}" data-isneededpromise="false">Webseite</a>
			
		

		
	
			
				
		
			<a class="contains-icon-email gs-btn" href="mailto:info@as-billing.de?subject=Anfrage%20%C3%BCber%20Gelbe%20Seiten" data-wipe="{&quot;listener&quot;:&quot;click&quot;, &quot;name&quot;:&quot;Trefferliste Email-Button&quot;, &quot;id&quot;:&quot;122085958708&quot;}" data-isneededpromise="false">E-Mail</a>
			
		

		
	
			
				
		
			
			<span class="contains-icon-route_finden gs-btn" data-wipe="{&quot;listener&quot;:&quot;click&quot;, &quot;name&quot;:&quot;Trefferliste Navigation-Button&quot;, &quot;id&quot;:&quot;122085958708&quot;}" data-parameters="{&quot;partner&quot;: &quot;googlemaps&quot;, &quot;searchquery&quot;: &quot;A%20%26%20S%20Billing%20Pflege-Service%20GmbH%20Kirchenberg%202-4%2090482%20N%C3%BCrnberg&quot;}" data-target="_blank">Route</span>
		

		
	
			
				
		
			
			<span class="contains-icon-details gs-btn" data-wipe="{&quot;listener&quot;:&quot;click&quot;, &quot;name&quot;:&quot;Trefferliste Actionbutton Mehr Details&quot;, &quot;id&quot;:&quot;122085958708&quot;}" data-parameters="{&quot;partner&quot;: &quot;gs&quot;, &quot;realId&quot;: &quot;2aeca1d2-2bc5-4070-ac4d-e16b10badca5&quot;, &quot;tnId&quot;: &quot;122085958708&quot;}">Mehr Details</span>
		

		
	
			
			
		</div>
	</div>

	</div>
			
			
			
			
		</article>

我第一次使用这些行

Dim post As Object

Set post = html.querySelectorAll(".mod-Treffer")

For i = 0 To post.Length - 1
Debug.Print post.Item(i).getElementsByTagName("h2")(0).innerText
Debug.Print post.Item(i).getElementsByTagName("Address")(0).getElementsByTagName("p")(1).innerText

'I am stuck with extracting the email
'HERE
Next i

此外,有时帖子对象没有电子邮件信息,因此我需要仅在找到时提取。

到目前为止的代码是这样的

    Const sURL As String = "https://www.gelbeseiten.de/Suche/Ambulante%20Pflegedienste/Bundesweit"
Dim http As MSXML2.XMLHTTP60, html As HTMLDocument

Set http = New MSXML2.XMLHTTP60
Set html = New MSHTML.HTMLDocument

With http
    .Open "Get", sURL, False
    .send
    html.body.innerHTML = .responseText
End With

Dim post As Object

Set post = html.querySelectorAll(".mod-Treffer")

Dim i As Long, r As Long
Range("A1").Resize(1, 3).Value = Array("Title", "Phone", "Email")
r = 2

For i = 0 To post.Length - 1
Cells(r, 1).Value = post.Item(i).getElementsByTagName("h2")(0).innerText
Cells(r, 2).Value = post.Item(i).getElementsByTagName("Address")(0).getElementsByTagName("p")(1).innerText


Next i

这是电子邮件部分的快照

【问题讨论】:

    标签: html excel vba web-scraping css-selectors


    【解决方案1】:

    原问题:

    在这种情况下,我将使用带有 contains 运算符的属性 = 值选择器通过字符串 mailto 来定位 href 属性。添加css选择器:[href*=mailto]

    如果您使用querySelectorAll("[href*=mailto]"),您可以测试.Length 属性是否大于0,或者使用querySelector 并测试if Not querySelector("[href*=mailto]") Is Nothing

    如果设置为变量

    Dim ele As Object
    
    Set ele = html.document.querySelector("[href*=mailto]")
    If Not ele Is Nothing Then
        Debug.Print ele.href  'do something with the href to parse out email
    End If
    

    更新问题:

    对于更新后的问题,我将在 nodeList 中将当前节点的 outerHTML 转移到代理 HTMLDocument 变量中,以便我可以再次利用 querySelector 方法。我会按课程定位电子邮件。

    Option Explicit
    
    Public Sub GetListingInfo()
    
        Const URL As String = "https://www.gelbeseiten.de/Suche/Ambulante%20Pflegedienste/Bundesweit"
        Dim http As MSXML2.XMLHTTP60, html As MSHTML.HTMLDocument
    
        Set http = New MSXML2.XMLHTTP60
        Set html = New MSHTML.HTMLDocument
    
        With http
            .Open "Get", URL, False
            .send
            html.body.innerHTML = .responseText
        End With
    
        Dim post As Object, html2 As MSHTML.HTMLDocument
    
        Set post = html.querySelectorAll(".mod-Treffer")
        Set html2 = New MSHTML.HTMLDocument
    
        Dim i As Long, emailNode As Object
    
        With ActiveSheet
    
            .Range("A1").Resize(1, 3).Value = Array("Title", "Phone", "Email")
    
            For i = 0 To post.Length - 1
    
                html2.body.innerHTML = post.Item(i).outerHTML
    
                .Cells(i + 2, 1).Value = html2.querySelector("h2").innerText
                .Cells(i + 2, 2).Value = html2.querySelector(".mod-AdresseKompakt__phoneNumber").innerText
    
                Set emailNode = html2.querySelector(".contains-icon-email")
    
                If Not emailNode Is Nothing Then .Cells(i + 2, 3).Value = Replace$(emailNode.href, "mailto:", vbNullString)
            Next i
        End With
    End Sub
    

    【讨论】:

    • 非常感谢。事实上,我会在我提到的 post 对象的循环中使用它,所以我将您的行更改为 Set ele = post.Item(i).querySelector("[href*=mailto]") 但这会引发错误。什么毛病?。我已经更新并把代码放到现在。
    • 除了 vba 中的文档,您不能使用 querySelector
    • 您希望检索多少封电子邮件?您将使用 querySelectorAll 来收集所有 mailto href 节点并循环提取 href
    • 我没有在您现在添加到问题的 url 上看到任何电子邮件。搜索也不返回任何结果。有没有可以看到“标题”、“电话”、“电子邮件”的网址?
    • 您不会注意到使用两个 HTMLDocument 的任何速度问题。不过,您可以使用 querySelector 访问更快的 css 选择器。
    【解决方案2】:

    非常感谢。 我可以用这些线弄清楚

        If InStr(post.Item(i).getElementsByTagName("a")(1).href, "mailto:") Then
        Debug.Print Split(Split(post.Item(i).getElementsByTagName("a")(1).href, "mailto:")(1), "?")(0)
    End If
    

    但我欢迎任何其他改进和了解更多信息的建议。 * 经过测试,如果在元素中找不到电子邮件,我会遇到错误。如何避免错误?我可以使用On Error Resume Next。但我希望处理错误而不是跳过它。

    ** 编辑: 我可以通过使用这种结构来解决第二点

        Dim emailObj As Object
    
    Set emailObj = post.Item(i).getElementsByTagName("a")(1)
    If Not emailObj Is Nothing Then
     If InStr(post.Item(i).getElementsByTagName("a")(1).href, "mailto:") Then
        Debug.Print Split(Split(post.Item(i).getElementsByTagName("a")(1).href, "mailto:")(1), "?")(0)
    End If
    

    代码有效,但有时无法正确抓取电子邮件.. 那是因为这一行

    Set emailObj = post.Item(i).getElementsByTagName("a")(1)
    

    有时对象未分配给 1。所以我的最后一个问题:无论分配的数字如何,我如何才能获取电子邮件数据?

    在循环中,我尝试了这条线并没有用处

    Set aNodeList = post.Item(i).querySelectorAll(".contains-icon-email")(0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多