我正在开展个人项目以自动填写USPS Click&发货表格,然后输出参考号#和发货确认#
到目前为止,我已经能够完成整个过程,但我不能为我的生活找出如何取出Ref#(这是我的订单#)和交付确认#
基本上,对于每个打包标签,您都会在页面中显示确认HTML页面的标签。
<tr class="smTableText">
<td style="border-top:solid 1px #AAAAAA; padding-bottom:4px;" valign="top">
<table cellpadding="0" cellspacing="0" border="0" style="margin:7px 0px 0px 5px;">
<tr>
<td valign="top" class="mainText" width=46>1 of 1</td>
<td valign="top" width=21><a href="javascript:toggleMoreInfo(0)" tabindex="19"><img src="/cns/images/common/button_plus.gif" height="11" width="11" border="0" hspace="0" vspace="0" id="Img1" style="margin-right:10px;" alt=""></a></td>
<td valign="top" width=203><div class="mainText" style="margin-bottom:10px; height:1em; overflow:hidden;" id="Div1">FIRSTLAST NAME<BR>STREET ADDRESS<BR>CITY, STATE ZIP5-ZIP4<div class="smTableText">email@address.net<BR>Ref#: 100000000<BR></div> </div><div class="smTableText"></div> </td>
</tr>
</table>
</td>
<td style="border-top:solid 1px #AAAAAA; padding-bottom:4px; padding-top:7px;" valign="top" class="smTableText"><div id="Div2" style="margin-left:7px; height:2.4em; overflow:hidden;"> Ship Date: 11/17/09<br> Weight: 0lbs 9oz<br> From: 48506<br></div></td>
<td style="border-top:solid 1px #AAAAAA; padding-bottom:4px; padding-right:15px; padding-top:7px;" valign="top" align="right" class="smTableText"><div class="smTableText" id="Div3" style="height:2.4em; overflow:hidden; margin-bottom:3px;">Priority Mail <br>Delivery Confirm.<br></div> <span style="font-weight:bold;" class="smTableText">Label Total</span></td>
<td style="border-top:solid 1px #AAAAAA; padding-bottom:4px; padding-right:15px; padding-top:7px;" valign="top" align="right" class="smTableText"><div class="smTableText" id="Div4" style="height:2.4em; overflow:hidden; margin-bottom:3px;">$4.80<br>$0.00<br></div><span class="smTableTextbold">$4.80</span></td>
</tr>
<tr class="smTableText"> <td colspan=4 style="height:20px;" valign="top"><div class="mainText" style="margin:0px; padding:4px 8px 0px 8px; display:block; border-top:solid 1px #AAAAAA;">Delivery Confirmation™ Label Number: <span class="mainTextbold">0000 1111 2222 3333 4444 55</span></div></td> </tr>
我需要做的是遍历整个页面并找到“Ref#:”捕获接下来的9个字符。
然后找到下一个"Label Number: <span class="mainTextbold">"
并捕获接下来的27个字符。
每对Ref#:和Label Number: <span class="mainTextbold">
都应该保存到一个数组中。
我猜这个正则表达式可能是我最好的选择吗? 任何人都可以提供一个如何工作的例子。 C#首选的VB.net也可以。
更新: 正如评论中所指出的,这不是XML,而是WebBrowser控件中显示页面的HTML代码。
我自动填写每个页面,然后调用提交按钮上的点击操作进入下一页.....问题是这最后一页,我需要的数据并不是整齐地写在一个独特的标记到该字段让我从...中拉出来。
更新#2 好吧,使用给出的例子,我提出了以下内容。 看起来像很多工作来提取2个值。我猜测必须有一种更有效的方法。
'Sub getdeliverynum(ByVal sText As String)
Sub getdeliverynum()
Me.MainTabControl.SelectedTab = USPSsiteTAB
WebBrowser1.Navigate("http://www.vaporstix.com/usps.html")
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
Dim input As String = WebBrowser1.DocumentText
Dim pattern As String = "Ref#: ([^<]+)[\S\s]*?Label Number: <span class=""mainTextbold"">([^<]+)"
For Each match As Match In Regex.Matches(input, pattern)
Dim instance As Double
Dim ref As String = ""
Dim track As String = ""
instance = 0
For Each group As Group In match.Groups
instance = instance + 1
If instance = 1 Then
'do nothing this is the full string....
ElseIf instance = 2 Then
ref = group.Value
ElseIf instance = 3 Then
track = group.Value
End If
Next
'replace with insert to db... this is for testing.
MsgBox("Ref: " + ref + vbCrLf + "Confirmation: " + track)
Next
End Sub
答案 0 :(得分:2)
您应该使用System.xml
并使用适当的解析器来完成这项工作。 Xpath
甚至导航XmlDocument
都可以让您实现所需目标。
Dim xpathDoc As XPathDocument
Dim xmlNav As XPathNavigator
Dim xmlNI As XPathNodeIterator
xpathDoc = New XPathDocument("c:\builder.xml")
xmlNav = xpathDoc.CreateNavigator()
xmlNI = xmlNav.Select("//span[@class='mainTextbold']")
While (xmlNI.MoveNext())
System.Console.WriteLine(xmlNI.Current.Name + " : " + xmlNI.Current.Value)
End While
我建议您查看there或there,了解有关如何从XmlDocument
像span[@class='mainTextbold']
这样的Xpath选择器会返回所有这些跨度。
根据Heinzi评论,您的文档似乎无效XHTML
,您应该使用TidyNet将其转换为XHTML,然后解析转换结果。
答案 1 :(得分:1)
要回答原始问题,考虑到所有关于使用正则表达式“解析”HTML的强制性警告,这里有一个正如你想要的正则表达式:
Ref#: (.{9})[\S\s]*?Label Number: <span class="mainTextbold">(.{27})
反向引用\1
将包含Ref#:
后的9个字符,\2
将包含Label number...
之后的27个字符
或者,为了使其更加健壮,您也可以使用
Ref#: ([^<]+)[\S\s]*?Label Number: <span class="mainTextbold">([^<]+)
这样,正则表达式将匹配除标记后的开口尖括号以外的任何字符。如果字符串中的正则表达式根本找不到匹配项,则会导致 lot 更多回溯。根据所使用的正则表达式引擎,如果使用所有格匹配,则可以避免这种情况:
Ref#: ([^<]++)[\S\s]*?Label Number: <span class="mainTextbold">([^<]++)
我支持使用正则表达式执行此任务的基本原理:
答案 2 :(得分:0)
关于提取值的更新问题:
For Each match As Match In Regex.Matches(input, pattern)
Dim ref As String = match.Groups(1).Value
Dim track As String = match.Groups(2).Value
' replace with insert to db... this is for testing.
MsgBox("Ref: " + ref + vbCrLf + "Confirmation: " + track)
Next
(未测试的)