以下网址包含数据和表格,我喜欢阅读表格的前两列。 xpatahSApply命令工作正常,但我需要调整两个以上的属性,我无法弄清楚。
url ="http://floodobservatory.colorado.edu/SiteDisplays/1544data.htm"
doc=htmlTreeParse(url,useInternal=TRUE)
解析数据的样本
<tr height="20" style="height:15.0pt">
<td height="20" class="xl6521398" align="right" style="height:15.0pt">11-Oct-13</td>
<td class="xl7321398">1853</td>
<td class="xl7321398"></td>
<td class="xl8121398">0.80</td>
<td class="xl7221398" align="right">4.87</td>
<td class="xl1521398"></td>
<td class="xl1521398"></td>
<td class="xl1521398"></td>
<td class="xl1521398"></td>
<td class="xl1521398"></td>
<td class="xl1521398"></td>
<td class="xl7421398"></td>
<td class="xl7421398"></td>
<td class="xl7421398"></td>
<td class="xl7421398"></td>
<td class="xl9621398"></td>
<td class="xl7421398"></td>
<td class="xl8121398"></td>
</tr>
我需要读取两个单元格中的值,其中一个对应于 date ,另一个对应于 streamflow discharge ,并且具有下面提到的属性
<td height="20" class="xl6521398" ...> and [<td class="xl7321398"..]
关于以上样本数据,我需要抓住“11-Oct-13”和“1853”。
我使用以下命令来获取'date'和'streamflow discharge'。
dates=xpathSApply(doc,"//td[@class='xl6521398']",xmlValue)
streamflowdischarge=xpathSApply(doc,"//td[@class='xl7321398']",xmlValue)
他们成功提取了信息,但提取的值包含来自其他表格/单元格的值,重要的是“日期”和“流量排放”不对应。
日期[1:10] [1]“1-Jan-98”“2-Jan-98”“3月1日-98”“31-Mar-98”“4月1日-98”“30-Apr-98”“5月1日 - 98" [8]“31-May-98”“6月1日 - 98”“30-Jun-98”
“31-Mar-98”介于“3月1日至98日”和“4月1日至98日”之间 - 一些无意识的事情
streamflowdischarge [1:10] [1]“3108”“3076”“3051”“3111”“3064”“3043”“3007”“3066”“378”“”
“3108”与“1-Jan-98”不对应 - 可以在网址查看
看起来有些表格/单元格具有相同的属性,我不想读取/抓取。在这方面,我认为我需要传递整个属性,即
<td height="20" class="xl6521398" align="right" style="height:15.0pt">
获取'日期',不知怎的,我应该调整,以便从同一个表中提取'streamflow discharge'。
非常感谢建议,以及是否还有其他选择。
我尝试了readHTMLTable,但收到错误“下标超出界限”
谢谢, 萨蒂什南比亚
答案 0 :(得分:4)
我输入了数据
url = "http://floodobservatory.colorado.edu/SiteDisplays/1544data.htm"
html = htmlParse(url)
然后查询包含您感兴趣的两个单元格类的表行,取每个单元格的第一个或第二个单元格
query = "//tr[./td[@class='xl6521398'] and ./td[@class='xl7321398']]/td[1]"
dates = xpathSApply(html, query, xmlValue)
query = "//tr[./td[@class='xl6521398'] and ./td[@class='xl7321398']]/td[2]"
flows = xpathSApply(html, query, xmlValue)
这些是我想你想要的
> df = data.frame(dates=as.Date(dates, "%e-%b-%y"), flows=as.integer(flows))
> nrow(df)
[1] 5808
> head(df, 3)
dates flows
1 1-Jan-98 1258
2 2-Jan-98 1584
3 3-Jan-98 1272
> tail(df, 3)
dates flows
5806 23-Nov-13 2878
5807 24-Nov-13 2852
5808 25-Nov-13 2738
我想秘诀是使用两列感兴趣的行选择(但也许这些是由用于制作网页的电子表格生成的类,与语义意义无关。数据?)对数据进行分组。更“完整”的抓取可能会创建行的节点集,然后查询标记为感兴趣的类的行(有时是几行),例如,
query = "//tr[./td[@class='xl6521398'] and ./td[@class='xl7321398']]"
nodes = getNodeSet(html, query)
date = lapply(nodes, xpathSApply, "./td[@class='xl6521398']", xmlValue)
flow = lapply(nodes, xpathSApply, "./td[@class='xl7321398']", xmlValue)
日期和流量元素是协调的,但每个日期可以有多个流量测量值。
> head(flow, 3)
[[1]]
[1] "1258" "" "1799" "2621" "1258"
[[2]]
[1] "1584" "" "1550" "2033" "978"
[[3]]
[1] "1272" "" "1104" "3515" "233"
> table(sapply(flow, length))
2 3 5
5577 15 216
所以我猜这是为了苏丹的Blue Nile;整齐
url = "http://floodobservatory.colorado.edu/SiteDisplays/Summary5.htm"
sites = htmlParse(url)
> sites["//tr[./td[1] = '1544']"]
[[1]]
<tr height="17" style="height:12.75pt"><td height="17" class="xl7226158" style="height:12.75pt">1544</td>
<td class="xl6926158"/>
<td class="xl7026158">13.0940</td>
<td class="xl7026158">33.9750</td>
<td class="xl6926158">5070</td>
<td class="xl6926158">Blue Nile</td>
<td class="xl6926158">Sudan</td>
<td class="xl6926158">2</td>
<td class="xl6926158">2</td>
<td class="xl7926158">173%</td>
<td class="xl8226158">15.88</td>
<td class="xl7126158">19-Nov-14</td>
<td class="xl7126158"/>
</tr>
attr(,"class")
[1] "XMLNodeSet"
答案 1 :(得分:3)
您可以在xpath:
中使用and
和|
运算符
path_xp <- '//td[@class="xl6521398" and @height="20"]|//td[@class="xl7321398"]'
res <- xpathSApply(doc,path_xp,xmlValue)
[1] "11-Oct-13" "1853" ""
请注意,此处有3个元素,因为您有2个元素,其属性类等于xl7321398。也许你应该更准确地提出你的要求,或者你可以移动第三个空元素。
res[nzchar(res)]
[1] "11-Oct-13" "1853"