Ale*_*aun 8 html html-parsing gumbo julia
这是示例 html 文件的公共链接。我想从文件中提取每组 CAN 和年度税收信息(下图中以红色突出显示的示例),并构建一个如下所示的数据框。
| Row | CAN | Crtf_NoCrtf | Tax_Year | Land_Value | Improv_Value | Total_Value | Total_Tax |
|-----+--------------+-------------+----------+------------+--------------+-------------+-----------|
| 1 | 184750010210 | Yes | 2016 | 16720 | 148330 | 165050 | 4432.24 |
| 2 | 184750010210 | Yes | 2015 | 16720 | 128250 | 144970 | 3901.06 |
| 3 | 184750010210 | Yes | 2014 | 16720 | 109740 | 126460 | 3412.63 |
| 4 | 184750010210 | Yes | 2013 | 16720 | 111430 | 128150 | 3474.46 |
| 5 | 184750010210 | Yes | 2012 | 16720 | 99340 | 116060 | 3146.17 |
| 6 | 184750010210 | Yes | 2011 | 16720 | 102350 | 119070 | 3218.80 |
| 7 | 184750010210 | Yes | 2010 | 16720 | 108440 | 125160 | 3369.97 |
| 8 | 184750010210 | Yes | 2009 | 16720 | 113870 | 130590 | 3458.14 |
| 9 | 184750010210 | Yes | 2008 | 16720 | 122390 | 139110 | 3629.85 |
| 10 | 184750010210 | Yes | 2007 | 16720 | 112820 | 129540 | 3302.72 |
| 11 | 184750010210 | Yes | 2006 | 12380 | 112760 | | 3623.12 |
| 12 | 184750010210 | Yes | 2005 | 19800 | 107400 | | 3882.24 |Run Code Online (Sandbox Code Playgroud)
如果无法将 CAN 插入到每一行,我可以单独导出 CAN 编号并找到一种方法将它们附加到包含税值的数据帧。我已经研究过为 python 使用漂亮的汤,但我是 python 的绝对新手,我编写的其余脚本都是用 Julia 编写的,所以我更愿意将所有内容都保留在一种语言中。
有什么方法可以实现我想要实现的目标吗?我看过Gumbo.jl,但找不到任何详细的文档/教程。
因此,Gumbo.jl将解析 HTML 并为您提供 HTML 文件结构的编程表示(称为 DOM - 文档对象模型)。这通常是一个 html 标签树,您可以遍历并提取您需要的数据。
为了更容易,您真正想要的是一种查询 DOM 的方法,这样您就可以提取所需的数据,而不必自己遍历整个树。该Cascadia.jl项目可以实现这个要求。它建立在 Gumbo 之上,并使用CSS 选择器作为查询语言。
因此,对于您的示例,您可以使用以下内容来提取所有CAN字段:
julia> using Gumbo
julia> using Cascadia
julia> h=parsehtml(read("/Users/aviks/Download/z1.html", String))
julia> c = matchall(Selector("td:containsOwn(\"CAN:\") + td span"), h.root)
13-element Array{Gumbo.HTMLNode,1}:
Gumbo.HTMLElement{:span}:
<span class="value">184750010210</span>
...
#print all the CAN values
julia> for x in c
println( x.children[1].text )
end
184750010210
186170040070
175630130020
172640020290
168330020230
156340030160
118210000020
190490040500
173480080430
161160010050
153510060090
050493000250
050470630910
Run Code Online (Sandbox Code Playgroud)
希望这能让您了解如何提取所需的所有数据。
当前的答案有点过时,因为该readall()功能不再存在。我将在下面更新他的答案。
以下是 Julia 包生态系统的总体细分(截至撰写本答案时):
要记住的关键一点是,Gumbo 将树格式的对象存储为HTMLNodes 或HTMLElements。所以大多数对象都有“父母”和“孩子”。要获取所需的数据,只需使用正确的选择器(使用 Cascadia)进行过滤,然后转到 Gumbo 树中的正确点即可。
avik 答案的更新版本:
using Requests, Cascadia, Gumbo
# r = get(url) # Normally, you'd put a url here, but I couldn't find a way to grab it without having to download it and read it locally
# h = parsehtml(String(r.data)) # Then normally you'd execute this
# Instead, I'm going to read in the html file as a string and give it to Gumbo
h = parsehtml(readstring("z1.html"))
# Exploring with the various structure of Gumbo objects:
println(fieldnames(h.root))
println(fieldnames(h.root.children))
println(size(h.root.children))
# aviks code:
c = matchall(Selector("td:containsOwn(\"CAN:\") + td span"), h.root);
for x in c
println( x.children[1].text )
end
Run Code Online (Sandbox Code Playgroud)
这个特定的网页比大多数网页更难抓取,因为它没有很好的 CSS 结构。
Cascadia README上有一些关于工作流程的很好的文档,但读完后我仍然有一些问题。对于其他人(就像我一样,昨天)来到此页面寻找 Julia 中的网页抓取指导的人,我创建了一个jupyter 笔记本,其中包含一个简单的示例,希望能够帮助您更详细地了解工作流程。