从使用RCurl抓取的网页中提取“干净”的UTF-8文本

15
使用R语言,我正在尝试爬取一个网页并将其中的文本保存到文件中。这些文本是日语。最终需要将其扩展到每天处理数百个页面。我已经有了一个可行的Perl解决方案,但我正在尝试将脚本迁移到R语言以减少在多种语言之间切换时的认知负荷。到目前为止,我还没有成功。相关问题似乎是关于保存csv文件将希伯来语写入HTML文件的问题。然而,我还没有根据那里的答案拼凑出一个解决方案。编辑:这个关于从R输出UTF-8的问题也很相关,但未得到解决。 这些页面来自Yahoo! Japan Finance,我的Perl代码如下:
use strict;
use HTML::Tree;
use LWP::Simple;
#use Encode;
use utf8;

binmode STDOUT, ":utf8";

my @arr_links = ();
$arr_links[1] = "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7203";
$arr_links[2] = "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7201";

foreach my $link (@arr_links){
    $link =~ s/"//gi;
    print("$link\n");
    my $content = get($link);
    my $tree = HTML::Tree->new();
    $tree->parse($content);
    my $bar = $tree->as_text;
    open OUTFILE, ">>:utf8", join("","c:/", substr($link, -4),"_perl.txt") || die;
    print OUTFILE $bar;
}

这个Perl脚本生成一个CSV文件,看起来像下面的截图,包含适当的汉字和假名,可以在离线情况下进行挖掘和操作: 由Perl脚本生成的CSV文件 我的R代码如下所示。这个R脚本并不完全复制了刚才给出的Perl解决方案,因为它没有剥离HTML并留下文本(这个答案提供了一种使用R的方法,但在这种情况下它对我不起作用),也没有循环等,但意图是相同的。
require(RCurl)
require(XML)

links <- list()
links[1] <- "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7203"
links[2] <- "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7201"

txt <- getURL(links, .encoding = "UTF-8")
Encoding(txt) <- "bytes"
write.table(txt, "c:/geturl_r.txt", quote = FALSE, row.names = FALSE, sep = "\t", fileEncoding = "UTF-8")

这个R脚本生成了下面屏幕截图所示的输出结果。基本上是垃圾。

CSV file produced by R script

我假设有一些HTML、文本和文件编码组合可以让我在R中生成类似于Perl解决方案的结果,但我找不到。我尝试抓取的HTML页面的头部显示字符集为utf-8,并且我已经在getURL调用和write.table函数中设置了编码为utf-8,但这仅此而已还不够。

问题: 如何使用R抓取上述网页并将文本保存为“格式正确”的日语文本,而不是看起来像行噪音的东西?

编辑:我添加了进一步的屏幕截图,以展示当我省略Encoding步骤时会发生什么。我得到的是Unicode代码,而不是字符的图形表示。这可能是某种与区域设置相关的问题,但在完全相同的区域设置下,Perl脚本确实提供了有用的输出。所以这仍然很困惑。 我的会话信息: R版本2.15.0 Patched (2012-05-24 r59442) 平台:i386-pc-mingw32/i386 (32-bit) 区域设置: 1 LC_COLLATE=English_United Kingdom.1252 2 LC_CTYPE=English_United Kingdom.1252
3 LC_MONETARY=English_United Kingdom.1252 4 LC_NUMERIC=C
5 LC_TIME=English_United Kingdom.1252
附加的基本包: 1 stats graphics grDevices utils datasets methods base

enter image description here


也许你不需要 Encoding(txt) <- "bytes",在我的环境中它可以正常工作。 - kohske
@kohske,感谢您的建议。我尝试了一次没有使用Encoding(),但不幸的是我没有成功。 - SlowLearner
2个回答

10
我似乎找到了一个答案,没有其他人发布过,所以我来发表一下。之前@kohske评论说,一旦删除Encoding()调用,代码就能够正常工作。这让我想到他可能有日语区域设置,这又暗示着我的机器存在某种方式影响R的区域设置问题 - 即使Perl避免了这个问题。我重新调整了搜索,并找到了这个问题关于如何在UTF-8文件中进行源代码处理,原帖作者遇到了类似的问题。答案涉及切换区域设置。我进行了实验,发现将我的区域设置切换为日语似乎解决了问题,如下图所示:

Output from updated R code

下面是更新的R代码。

require(RCurl)
require(XML)

links <- list()
links[1] <- "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7203"
links[2] <- "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7201"

print(Sys.getlocale(category = "LC_CTYPE"))
original_ctype <- Sys.getlocale(category = "LC_CTYPE")
Sys.setlocale("LC_CTYPE","japanese")

txt <- getURL(links, .encoding = "UTF-8")

write.table(txt, "c:/geturl_r.txt", quote = FALSE, row.names = FALSE, sep = "\t", fileEncoding = "UTF-8")
Sys.setlocale("LC_CTYPE", original_ctype)

所以我们必须通过编程来处理语言环境。说实话,我有点尴尬,因为在2012年的Windows上似乎需要这样的解决方法。正如我上面提到的,同样版本的Windows和语言环境下的Perl以某种方式规避了此问题,而不需要我更改系统设置。

以上更新后的R代码的输出当然是HTML格式的。对于那些感兴趣的人,以下代码可以很好地剥离HTML并保存原始文本,但结果需要进行大量整理。

require(RCurl)
require(XML)

links <- list()
links[1] <- "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7203"
links[2] <- "http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7201"

print(Sys.getlocale(category = "LC_CTYPE"))
original_ctype <- Sys.getlocale(category = "LC_CTYPE")
Sys.setlocale("LC_CTYPE","japanese")

txt <- getURL(links, .encoding = "UTF-8")
myhtml <- htmlTreeParse(txt, useInternal = TRUE)
cleantxt <- xpathApply(myhtml, "//body//text()[not(ancestor::script)][not(ancestor::style)][not(ancestor::noscript)]", xmlValue)

write.table(cleantxt, "c:/geturl_r.txt", col.names = FALSE, quote = FALSE, row.names = FALSE, sep = "\t", fileEncoding = "UTF-8")
Sys.setlocale("LC_CTYPE", original_ctype)

0

嗨,我写了一个网络爬虫引擎,可以在主列表页面中深度嵌入的网页上进行数据抓取。我想知道在将数据导入R之前,将其用作您的网络数据聚合器是否有帮助?

引擎的位置在这里 http://ec2-204-236-207-28.compute-1.amazonaws.com/scrap-gm

我创建的用于抓取您所考虑的页面的示例参数如下。

{
  origin_url: 'http://stocks.finance.yahoo.co.jp/stocks/detail/?code=7203',
  columns: [
    {
      col_name: 'links_name',
      dom_query: 'a'   
    }, {
      col_name: 'links',
      dom_query: 'a' ,
      required_attribute: 'href'
    }]
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接