使用 xml 和 r 解析元 name/content
parsing meta name/content using xml and r
关于以下问题的答案:how to get information within <meta name...> tag in html using htmlParse and xpathSApply
我的问题:
html <- htmlParse(domain, useInternalNodes=T);
names <- html['//meta/@name']
content <- html['//meta/@content']
cbind(names, content)
页面中的元标记是:
<meta name="description" content="blah, blah...." />
<meta name="keywords" content="keyword1, keyword2" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="google-site-verfication" content="1234jalsdkfjasdf928374-293423" />
我找到的是这样的:
length(names)
[1] 3
length(content)
[1] 4
names content
[1, ] "description" [1, ] "blah, blah...."
[2, ] "keywords" [2, ] "keyword1, keyword2"
[3, ] "google-site-verification" [3, ] "text/html; charset=UTF-8"
[4, ] "description" [4, ] "1234jalsdkfjasdf928374-293423"
似乎解析器在 "http-equiv" 上出错并返回 next 代码行 "google-site-verification" 但仍然返回 "content" "http-equiv",然后因为没有更多的 "names",cbind 再次环绕到 "description" 以匹配最后一行内容,即实际的 "google-site-verification"。
似乎是一个简单的修复,到目前为止,我所做的任何条件都不起作用,我怎样才能做到这一点?
我知道你想出了你需要的东西(这与原来的 q 不匹配)但我们将以 whosebug.com 为例,因为我已经将它编码为我的补充原答案:
library(XML)
doc <- htmlParse("http://whosebug.com/", useInternalNodes=TRUE)
具有以下 <meta>
个标签:
<meta name="twitter:card" content="summary">
<meta name="twitter:domain" content="whosebug.com"/>
<meta property="og:type" content="website" />
<meta property="og:image" itemprop="image primaryImageOfPage" content="http://cdn.sstatic.net/Whosebug/img/apple-touch-icon@2.png?v=fde65a5a78c6" />
<meta name="twitter:title" property="og:title" itemprop="title name" content="Stack Overflow" />
<meta name="twitter:description" property="og:description" itemprop="description" content="Q&A for professional and enthusiast programmers" />
<meta property="og:url" content="http://whosebug.com/"/>
并非每个标签都有 name
属性,实际上在 7 个标签中,只有 4 个:
length(doc["//meta/@property"])
## [1] 4
注意这与做的一样:
length(xpathSApply(doc, "//meta/@name"))
## [1] 4
这几乎就是幕后发生的事情。
它只会返回搜索中的真实信息。如果你这样做,你可以看到它的布局:
xpathSApply(doc, "//meta", xmlGetAttr, "name")
## [[1]]
## [1] "twitter:card"
##
## [[2]]
## [1] "twitter:domain"
##
## [[3]]
## NULL
##
## [[4]]
## NULL
##
## [[5]]
## [1] "twitter:title"
##
## [[6]]
## [1] "twitter:description"
##
## [[7]]
## NULL
由于 NULL
s,该列表在转换为向量时会截断为 4 个条目。 rvest
(原始答案在提取时只是 "smarter"。
原始答案
使用 rvest
,您可以非常快速地将所有 <meta>
属性抓取到数据框中(如果这就是您想要做的):
library(rvest)
library(dplyr)
pg <- html("http://facebook.com/")
all_meta_attrs <- unique(unlist(lapply(lapply(pg %>% html_nodes("meta"), html_attrs), names)))
dat <- data.frame(lapply(all_meta_attrs, function(x) {
pg %>% html_nodes("meta") %>% html_attr(x)
}))
colnames(dat) <- all_meta_attrs
glimpse(dat)
## Observations: 19
## Variables:
## $ charset (fctr) utf-8, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ http-equiv (fctr) NA, refresh, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ content (fctr) NA, 0; URL=/?_fb_noscript=1, default, Facebook, h...
## $ name (fctr) NA, NA, referrer, NA, NA, NA, NA, NA, NA, NA, NA,...
## $ id (fctr) NA, NA, meta_referrer, NA, NA, NA, NA, NA, NA, NA...
## $ property (fctr) NA, NA, NA, og:site_name, og:url, og:image, og:lo...
但它也会可靠地为您提取属性:
pg %>% html_nodes("meta") %>% html_attr("http-equiv")
## [1] NA "refresh" NA
## [4] NA NA NA
## [7] NA NA NA
## [10] NA NA NA
## [13] NA NA NA
## [16] NA NA NA
## [19] "X-Frame-Options"
所以我想通了,至少我想通了。最终我只需要提取 "keywords" 和 "descriptions"。需要更改的代码是:
这个……
html <- htmlParse(domain, useInternalNodes=T);
names <- html['//meta/@name']
content <- html['//meta/@content']
对此...
html <- htmlParse(domain, useInternalNodes=T);
**keywords <- html['//meta[@name="keywords"]/@content']
description <- html['//meta[@name="description"]/@content']**
干杯
关于以下问题的答案:how to get information within <meta name...> tag in html using htmlParse and xpathSApply
我的问题:
html <- htmlParse(domain, useInternalNodes=T);
names <- html['//meta/@name']
content <- html['//meta/@content']
cbind(names, content)
页面中的元标记是:
<meta name="description" content="blah, blah...." />
<meta name="keywords" content="keyword1, keyword2" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="google-site-verfication" content="1234jalsdkfjasdf928374-293423" />
我找到的是这样的:
length(names)
[1] 3
length(content)
[1] 4
names content
[1, ] "description" [1, ] "blah, blah...."
[2, ] "keywords" [2, ] "keyword1, keyword2"
[3, ] "google-site-verification" [3, ] "text/html; charset=UTF-8"
[4, ] "description" [4, ] "1234jalsdkfjasdf928374-293423"
似乎解析器在 "http-equiv" 上出错并返回 next 代码行 "google-site-verification" 但仍然返回 "content" "http-equiv",然后因为没有更多的 "names",cbind 再次环绕到 "description" 以匹配最后一行内容,即实际的 "google-site-verification"。 似乎是一个简单的修复,到目前为止,我所做的任何条件都不起作用,我怎样才能做到这一点?
我知道你想出了你需要的东西(这与原来的 q 不匹配)但我们将以 whosebug.com 为例,因为我已经将它编码为我的补充原答案:
library(XML)
doc <- htmlParse("http://whosebug.com/", useInternalNodes=TRUE)
具有以下 <meta>
个标签:
<meta name="twitter:card" content="summary">
<meta name="twitter:domain" content="whosebug.com"/>
<meta property="og:type" content="website" />
<meta property="og:image" itemprop="image primaryImageOfPage" content="http://cdn.sstatic.net/Whosebug/img/apple-touch-icon@2.png?v=fde65a5a78c6" />
<meta name="twitter:title" property="og:title" itemprop="title name" content="Stack Overflow" />
<meta name="twitter:description" property="og:description" itemprop="description" content="Q&A for professional and enthusiast programmers" />
<meta property="og:url" content="http://whosebug.com/"/>
并非每个标签都有 name
属性,实际上在 7 个标签中,只有 4 个:
length(doc["//meta/@property"])
## [1] 4
注意这与做的一样:
length(xpathSApply(doc, "//meta/@name"))
## [1] 4
这几乎就是幕后发生的事情。
它只会返回搜索中的真实信息。如果你这样做,你可以看到它的布局:
xpathSApply(doc, "//meta", xmlGetAttr, "name")
## [[1]]
## [1] "twitter:card"
##
## [[2]]
## [1] "twitter:domain"
##
## [[3]]
## NULL
##
## [[4]]
## NULL
##
## [[5]]
## [1] "twitter:title"
##
## [[6]]
## [1] "twitter:description"
##
## [[7]]
## NULL
由于 NULL
s,该列表在转换为向量时会截断为 4 个条目。 rvest
(原始答案在提取时只是 "smarter"。
原始答案
使用 rvest
,您可以非常快速地将所有 <meta>
属性抓取到数据框中(如果这就是您想要做的):
library(rvest)
library(dplyr)
pg <- html("http://facebook.com/")
all_meta_attrs <- unique(unlist(lapply(lapply(pg %>% html_nodes("meta"), html_attrs), names)))
dat <- data.frame(lapply(all_meta_attrs, function(x) {
pg %>% html_nodes("meta") %>% html_attr(x)
}))
colnames(dat) <- all_meta_attrs
glimpse(dat)
## Observations: 19
## Variables:
## $ charset (fctr) utf-8, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...
## $ http-equiv (fctr) NA, refresh, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ content (fctr) NA, 0; URL=/?_fb_noscript=1, default, Facebook, h...
## $ name (fctr) NA, NA, referrer, NA, NA, NA, NA, NA, NA, NA, NA,...
## $ id (fctr) NA, NA, meta_referrer, NA, NA, NA, NA, NA, NA, NA...
## $ property (fctr) NA, NA, NA, og:site_name, og:url, og:image, og:lo...
但它也会可靠地为您提取属性:
pg %>% html_nodes("meta") %>% html_attr("http-equiv")
## [1] NA "refresh" NA
## [4] NA NA NA
## [7] NA NA NA
## [10] NA NA NA
## [13] NA NA NA
## [16] NA NA NA
## [19] "X-Frame-Options"
所以我想通了,至少我想通了。最终我只需要提取 "keywords" 和 "descriptions"。需要更改的代码是:
这个……
html <- htmlParse(domain, useInternalNodes=T);
names <- html['//meta/@name']
content <- html['//meta/@content']
对此...
html <- htmlParse(domain, useInternalNodes=T);
**keywords <- html['//meta[@name="keywords"]/@content']
description <- html['//meta[@name="description"]/@content']**
干杯