coderLMN / AutomatedDataCollectionWithR

《基于 R 语言的自动化数据采集技术》读者讨论区
28 stars 10 forks source link

P246,meta()函数得不到和书中同样的结果 #18

Open zchunc opened 6 years ago

zchunc commented 6 years ago
### 10.2处理文本数据 tm组件
### 新闻公告是HTML格式,放进语料库之前,去掉所有标签和与新闻公告无关的文本
### 降噪,留下新闻文本,和发布单位和发布日期(元信息)
### 元信息:描述信息的信息
### 新闻公告保存在<div class="govspeak">之后
### 如下调用获取该新闻公告对象(release)
library(XML)
library(RCurl)
library(stringr)
library(tm)

tmp <- readLines("~/Press_Releases/1.html")
str(tmp)
tmp <- str_c(tmp, collapse = "")
tmp <- htmlParse(tmp)
release <- xpathSApply(tmp, "//div[@class = 'govspeak']", xmlValue)
release

# 在对整个语料库进行迭代之前,要编写两个查询来提取元信息,发布单位和发布日期
organisation <- xpathSApply(tmp, "//dd[@class = 'app-c-publisher-metadata__definition']", xmlValue)
organisation
publication <- str_trim(xpathSApply(tmp, "//div[@class = 'app-c-published-dates']", xmlValue)[1])
# publication <- str_trim(publication)
publication

### 可以创建一个循环,对所有公告进行操作并放进一个语料库里
### 通过对上面配置好的第一个新闻公告调用Corpus(),文本新闻公告(即release对象)是在一个VectorSource()进行包装
### 该语料库是从保存在一个字符向量中的文本里创建出来的
### install.packages("tm")
### library(tm)
release_corpus <- Corpus(VectorSource(release))
release_corpus[[1]]
### 为了把两个元信息(即发布单位和发布时间)加入文本里,使用meta()函数
meta(release_corpus[[1]], "organisation") <- organisation[1]
meta(release_corpus[[1]], "publication") <- publication
meta(release_corpus[[1]])

##### 运行结果为(如下),没有organisation和publication的信息,
##### 请问老师这是什么原因:
> meta(release_corpus[[1]])
  author       : character(0)
  datetimestamp: 2017-12-26 12:31:37
  description  : character(0)
  heading      : character(0)
  id           : 1
  language     : en
  origin       : character(0)

### 第2个问题:
运行下面的代码结果为:Error in x$content[[i]] : subscript out of bounds,
请问老师这是什么原因
n <- 1
for(i in 2:length(list.files("~/Press_Releases/"))){
  tmp <- readLines(str_c("~/Press_Releases/", i, ".html"))
  tmp <- str_c(tmp, collapse = "")
  tmp <- htmlParse(tmp)
  release <- xpathSApply(tmp, 
                         "//div[@class='govspeak']", xmlValue) #现在的网页结构节点变化了
  organisation <- xpathSApply(tmp, 
                              "//dd[@class = 'app-c-publisher-metadata__definition']", xmlValue)
  publication <- str_trim(xpathSApply(tmp, 
                                      "//div[@class='app-c-published-dates']", xmlValue)[1])
  if(length(release) != 0){
    n <- n + 1
    release_corpus <- Corpus(VectorSource(release))
    # release_corpus <- c(release_corpus, tmp_corpus)
    meta(release_corpus[[n]], "organisation") <- organisation[1]
    meta(release_corpus[[n]], "publication") <- publication
  }
}
coderLMN commented 6 years ago

第一个问题的原因有可能是没有取到数据。我怀疑是前面的 .html 文件下载没有成功,你可以看看本地的 ~/Press_Releases/ 文件夹里是否有 245 个 .html 文件(原书翻译的时候是 747 个,现在已经少了),会不会是因为你还没有建这个文件夹呢。我下载数据之后,再按照你上面的这些代码执行,结果是没有问题的:

> meta(release_corpus[[1]])
  author       : character(0)
  datetimestamp: 2017-12-28 03:56:52
  description  : character(0)
  heading      : character(0)
  id           : 1
  language     : en
  origin       : character(0)
  organisation : Prime Minister's Office, 10 Downing Street
  publication  : Published 1 July 2010

因为我看不到你那边的数据,所以只能猜测一下。如果我的猜测不对,请告诉我。

第二个问题在于你改掉的那行代码:

  release_corpus <- Corpus(VectorSource(release))
  # release_corpus <- c(release_corpus, tmp_corpus)

这样在循环里每次都把 release_corpus 给初始化了,所以在访问 release_corpus[[n]] 的时候会越界。把它改回原来的代码就好了:

  tmp_corpus <- Corpus(VectorSource(release))     #构建一个临时语料
  release_corpus <- c(release_corpus, tmp_corpus)   #把临时语料加入到总的语料中