0

THOMAS (thomas.loc.gov) でホストされている議会記録からテキストを自動的にスクレイピングする R スクリプトに取り組んでいます。

THOMAS を使用すると、ユーザーは議会記録の毎日の問題を「閲覧」できます。最適な方法は、次の手順に従うことだと思います。

  1. 各日刊号へのリンクを一覧表示します (例: http://thomas.loc.gov/cgi-bin/query/B?r101:@FIELD(FLD003+h)+@FIELD(DDATE+19901019は次のリンクです) 。下院での 1990 年 10 月 19 日号)
  2. リンクごとに、個々の「記事」へのすべてのリンクを取得します (記事は、30 分間のみ有効な一時的な検索クエリでリンクされています)。
  3. 記事をループして、「印刷に適した」バージョンのリンクをたどってください (さまざまな理由から、これが最良の選択肢のように思えます。第 37 条 -- 「HR 5229 に関する会議報告書、運輸省および関連機関の歳出法、1991 年」 -- HR 5229 に関する議論のセクションへのリンクのリストを含む新しいページに移動します。 -Friendly' バージョンでは、すべてのテキストが 1 か所に一覧表示されます。
  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"

必要な場合 (「gi-bin」の代わりに「cgi-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)外側のループで1回、内側のループで1回行います)。readLines次にparseHTML、取得したオブジェクトでサーバー要求を半分にすることができます。
  3. この行 as.vector(xpathSApply(doc2, "//a/@href"))には何も保存されません。
  4. tやのような多くの変数名を再利用して、uさまざまな時点でさまざまなことを意味します。これは混乱を招き、ある時点で必然的に問題を引き起こします。
于 2013-06-28T17:36:12.677 に答える