0

我一直在研究一个 R 脚本,它会自动从托管在 THOMAS (thomas.loc.gov) 的国会记录中抓取文本。

THOMAS 允许用户“浏览”国会记录的每日问题。我认为最好的方法是遵循以下步骤:

  1. 列出每个每日问题的链接(例如:http ://thomas.loc.gov/cgi-bin/query/B?r101:@FIELD(FLD003+h)+@FIELD(DDATE+19901019是1990 年 10 月 19 日在众议院发行)
  2. 对于每个链接,获取指向单个“文章”的所有链接(文章通过仅在 30 分钟内有效的临时搜索查询链接到该链接)。
  3. 循环浏览文章并点击“打印机友好”版本的链接(出于各种原因,这似乎是最佳选择 - 例如,如果您查看上面链接的 10/19/1990 House 问题并单击关于第 37 条——“关于 HR 5229 的会议报告,运输部和相关机构拨款法案,1991 年”——您将被引导到一个新页面,其中包含指向 HR 5229 辩论部分的链接列表。 -friendly' 版本在一个地方列出了所有文本。
  4. 从适合打印的页面中刮取文本

我在第 3 步挂断了。出于某种原因,它总是返回“404 Not Found”错误。

下面的代码得到了大部分的方式:

setwd("U:/Congressional Record")
require(XML)

root <- "http://thomas.loc.gov/"
url <- "http://thomas.loc.gov/home/Browse.php?&n=Issues&c=101"

^^指向第 101 届大会的链接

doc <- htmlParse(url)
links <- as.vector(xpathSApply(doc, "//a/@href"))
hou <- grep("\\+h\\)", links)
sen <- grep("\\+s\\)", links)

links <- sort(c(links[hou], links[sen]))
link.ex <- 'href=\\"[^]].*<em>'
title.ex <- '[0-9]+\\s+\\.\\s+\\w*' 
timeout <- 'Search results in THOMAS are temporary and are deleted 30 minutes after creation.Please try your search again.'

^^从页面获取链接并设置所需的正则表达式以供下面使用。

txt <- NULL ##container for scraped text
for (j in links) { ##begin loop through issues
    ##append a break for each day
    txt <- c(txt, '*#*#start new day#*#*', j)
    u <- paste(root, j, sep="")
    doc <- htmlParse(u)
    ##pull out the links
    l <- as.vector(xpathSApply(doc, "//a/@href"))
    ##find subset only the links that lead to text from CR
    s <- grep("query", l)

    ##get a list of titles for each entry
    t <- readLines(u)
    ##clean it up a little
    t <- gsub('</*\\w*/*>', '', t, perl=TRUE)
    ##find the titles
    tInds <- grep(title.ex, t)
    tEnds <- regexpr('<', t[tInds])
    titles <- substr(t[tInds], 1, tEnds-2)

    for (k in 1:length(s)) { ##begin loop through articles of the daily issue
        u <- paste(root, l[s[k]], sep='')
        t <- readLines(u)
        doc2 <- htmlParse(u)
        as.vector(xpathSApply(doc2, "//a/@href"))
        ##refresh the search if it has taken too long
        timed <- grep(timeout, t)
        if (length(timed)>0) {
            u <- paste(root, j, sep="")
            doc <- htmlParse(u)
            ##pull out the links
            l <- as.vector(xpathSApply(doc, "//a/@href"))   
            u <- paste(root, l[k], sep='')
            t <- readLines(u)
        }

        ##find the 'printer friendly' link
        ##for some reason the printer link doesn't work when I try to
        ##automatically scrape it from the site...

        i <- grep('Printer Friendly Display', t)
        ##extract the link and follow it
        pr <- regexpr(link.ex, t[i], perl=TRUE)
        li <- paste(root, 
            substr(t[i], pr[1]+8, pr[1]+attr(pr, 'match.length')[1]-7),
            sep='')
        t <- readLines(li)

        ##clean the text
        t <- gsub('</*\\w*/*>', '', t, perl=TRUE)

        ##code to scrape the text...

    } ##end loop through articles

} ##end loop through issues
4

1 回答 1

0

这条线是你的问题:

li <- paste(root, 
            substr(t[i], pr[1]+8, pr[1]+attr(pr, 'match.length')[1]-7),
            sep='')

它给你,例如:

> li
[1] "http://thomas.loc.gov/gi-bin/query/C?r101:./temp/~r101PhW9pi"

当您需要时(使用“cgi-bin”而不是“gi-bin”):

"http://thomas.loc.gov/cgi-bin/query/C?r101:./temp/~r101PhW9pi"

关于您的代码的其他一些评论:

  1. txt <- c(txt, '*#*#start new day#*#*', j)是一种非常低效的向量增长方式。
  2. doc <- htmlParse(u)并且t <- readLines(u)几乎是多余的(您在外循环中执行一次,在内部循环中执行一次)。readLines然后,您可以parseHTML在检索到的对象上将您的服务器请求减半。
  3. 这条线 as.vector(xpathSApply(doc2, "//a/@href"))不存储任何东西。
  4. 你重用了很多变量名,比如tand u,在不同的时间点表示不同的东西,这很容易混淆,并且在某些时候不可避免地会给你带来问题。
于 2013-06-28T17:36:12.677 回答