首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有pup的HTML解析

带有pup的HTML解析
EN

Unix & Linux用户
提问于 2020-05-29 17:39:19
回答 2查看 3.6K关注 0票数 5

我试图用小狗解析一个HTML页面。这是一个命令行HTML解析器,它接受一般的HTML选择器。我知道我可以使用我已经安装在我的机器上的Python,但是我想学习如何使用pup来练习命令行。

我想从https://ucr.fbi.gov/crime-in-the-u.s/2018/crime-in-the-u.s.-2018/topic-pages/tables/table-1上刮走的网站

我创建了一个html文件:

代码语言:javascript
复制
curl https://ucr.fbi.gov/crime-in-the-u.s/2018/crime-in-the-u.s.-2018/topic-pages/tables/table-1 > fbi2018.html

如何提取一列数据,如“人口”?

这是我最初写的命令:

代码语言:javascript
复制
cat fbi2018.html | grep -A1 'cell31 ' | grep -v 'cell31 ' | sed 's/text-align: right;//' | sed 's/<[/]td>//' | sed 's/--//' | sed '/^[[:space:]]*$/d' | sort -nk1,1 

它确实有效,但这是一种丑陋的,讨厌的方法,这就是为什么我想使用小狗。我注意到,我所需要的列“填充”中的所有值都在headers="cell 31 .."标记中的某个位置。例如:

代码语言:javascript
复制
323,405,935

我想提取它的标记中有这个特定标题的所有值,在这个特定的例子中,它将是323,405,935

然而,似乎小狗中的多个选择器不起作用。到目前为止,我可以选择所有td元素:

代码语言:javascript
复制
cat fbi2018.html | pup 'td'

但我不知道如何选择包含特定查询的标题。

编辑:输出应该是:

代码语言:javascript
复制
272,690,813
281,421,906
285,317,559
287,973,924
290,788,976
293,656,842
296,507,061
299,398,484
301,621,157
304,059,724
307,006,550
309,330,219
311,587,816
313,873,685
316,497,531
318,907,401
320,896,618
323,405,935
325,147,121
327,167,434
EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2020-05-30 05:41:39

TLDR

如果要在该表的“填充”下使用整列,请使用此方法:

代码语言:javascript
复制
... | pup 'div#table-data-container:nth-of-type(3) td.group1 text{}'

基本用法

pup确实支持多个选择器。例如,如果您想在下面抓取wanted text!!

代码语言:javascript
复制
$ cat file.html

  
    
        some text 
        some other text. 
    
    
        wanted text!! 
        some other text. 
    
  


$ cat file.html | pup 'div table tr.class-b td#aaa'

 wanted text!!

然后添加text{}只获取文本:

代码语言:javascript
复制
$ cat file.html | pup 'div table tr.class-b td#aaa text{}'
 wanted text!!

所以在你的情况下应该是:

代码语言:javascript
复制
$ cat fbi2018.html | pup 'td#cell211 text{}'

323,405,935

或者更好的是,您不必下载页面,只需将curl输送到pup

代码语言:javascript
复制
url="https://ucr.fbi.gov/crime-in-the-u.s/2018/crime-in-the-u.s.-2018/topic-pages/tables/table-1"
curl -s "$url" | pup 'td#cell211 text{}'

解释

如果您想要从整个列中获得值,那么您应该知道要抓取的元素的特征。

在这种情况下,“人口”列从给定的链接。在页面上,有两个用

...包装的表,如果使用... | pup 'div#table-data-container',它还会从第二个表中获取数据。你不会想要那样的。

pup怎么知道你想要第一张桌子?还有另一个提示。正如你所看到的,几乎没有

s,你的桌子在第三天。所以您可以使用CSS的psuedo类,在本例中是div#table-data-container:nth-of-type(3)

然后,列有唯一的选择器作为td.group1

将它们组合在一起,然后将其输送到grep -v -e '^,以消除空白。

代码语言:javascript
复制
... | pup 'div#table-data-container:nth-of-type(3) td.group1 text{}' | grep -v -e '^你会得到你想要的272,690,813
281,421,906
285,317,559
...
327,167,434,以消除空白。

A26

你会得到你想要的

A27

你会得到你想要的

A27,以消除空白。

A26

你会得到你想要的

A27

票数 7
EN

Unix & Linux用户

发布于 2020-05-29 17:44:46

这里有两个问题: 1)分析HTML表中的值,2)执行所需的操作(min、max等)

我不认为你能一条条地做到这一点。我喜欢将HTML表转换为.csv,然后对CSV进行操作的想法。您可以使用AWK,但是我会使用Python库Pandas。如果你能避免的话,为什么要写bash?

我找到了一种使用bash将HTML表转换为.csv 这里的方法。

使用AWK对列进行平均值的一个示例是这里

票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/589798

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档