【问题标题】:R Scrape web page linksR 抓取网页链接
【发布时间】:2015-11-20 17:18:22
【问题描述】:

我想这里一定有一个简单的答案,但我似乎找不到。

我正在抓取各种网页,我想从网页中拉下所有链接。我正在使用 htmlParse 来执行此操作,并且已经完成了大约 95%,但需要一些帮助。

这是我抓取网页的代码

MyURL <- "http://stackoverflow.com/"
MyPage <- htmlParse(MyURL) # Parse the web page
URLroot <- xmlRoot(MyPage) # Get root node

一旦我有了根节点,我就可以运行它来获取 a 节点

URL_Links <- xpathSApply(URLroot, "//a") # get all hrefs from root

这给了我这样的输出

[[724]]
<a href="//area51.stackexchange.com" title="proposing new sites in the Stack Exchange network">Area 51</a> 

[[725]]
<a href="//careers.stackoverflow.com">Stack Overflow Careers</a> 

[[726]]
<a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license">cc by-sa 3.0</a> 

或者,我可以运行它

URL_Links_values = xpathSApply(URLroot, "//a", xmlGetAttr, "href") # Get all href values

只获取这样的 HREF 值

[[721]]
[1] "http://creativecommons.org/licenses/by-sa/3.0/"

[[722]]
[1] "http://blog.stackoverflow.com/2009/06/attribution-required/"

但是,我正在寻找一种轻松获取 HREF 值和链接名称的方法,最好将其加载到数据框或矩阵中,而不是返回此值

<a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license">cc by-sa 3.0</a> 
<a href="http://blog.stackoverflow.com/2009/06/attribution-required/" rel="license">attribution required</a> 

我明白了

                  Name                                                        HREF
1         cc by-sa 3.0              http://creativecommons.org/licenses/by-sa/3.0/
2 attribution required http://blog.stackoverflow.com/2009/06/attribution-required/

现在我可以获取 URL_Links 的输出并执行一些正则表达式或拆分字符串以获取此数据,但似乎应该使用 XML 包更简单的方法来执行此操作。

有没有简单的方法来做我想做的事?

编辑:

刚刚发现我可以这样做来获取 URL 名称

URL_Links_names <- xpathSApply(URLroot, "//a", xmlValue) # Get all href values

但是当我运行它时

df <- data.frame(URL_Links_names, URL_Links_values)

我收到此错误

Error in data.frame("//stackoverflow.com", "http://chat.stackoverflow.com",  : arguments imply differing number of rows: 1, 0

我猜有没有名字的链接,那么对于任何没有名字的链接,我该如何让它 retrn "" 或 NA 呢?

【问题讨论】:

    标签: r web-scraping html-parsing


    【解决方案1】:

    html 中似乎缺少几个 href 链接。因为xmlGetAttr() 在没有请求属性时返回NULL,所以您可以使用is.null() 找到它们。然后,您可以将其放入 if() 条件中,为缺少的字符串包含一个空字符串,否则为 href 属性。无需对根节点进行子集化。

    library(XML)
    ## parse the html document
    doc <- htmlParse("http://stackoverflow.com/")
    ## use the [.XMLNode accessor to drop into 'a' and then apply our functions
    getvals <- lapply(doc["//a"], function(x) {
        data.frame(
            ## get the xml value
            Name = xmlValue(x, trim = TRUE), 
            ## get the href link if it exists
            HREF = if(is.null(att <- xmlGetAttr(x, "href"))) "" else att,
            stringsAsFactors = FALSE
        )
    })
    ## create the full data frame
    df <- do.call(rbind, getvals)
    ## have a look
    str(df)
    # 'data.frame': 697 obs. of  2 variables:
    #  $ Name: chr  "current community" "chat" "Stack Overflow" "Meta Stack Overflow" ...
    #  $ HREF: chr  "//stackoverflow.com" "http://chat.stackoverflow.com" "//stackoverflow.com" "http://meta.stackoverflow.com" ...
    
    tail(df)
    #                       Name                                                        HREF
    # 692             Stack Apps                                             //stackapps.com
    # 693    Meta Stack Exchange                                    //meta.stackexchange.com
    # 694                Area 51                                  //area51.stackexchange.com
    # 695 Stack Overflow Careers                                 //careers.stackoverflow.com
    # 696           cc by-sa 3.0              http://creativecommons.org/licenses/by-sa/3.0/
    # 697   attribution required http://blog.stackoverflow.com/2009/06/attribution-required/
    

    【讨论】:

      【解决方案2】:

      我的目标是查看所有链接名称,然后确定我需要哪个 URL。我没有找到一种方法来获取我想要的所有数据框,但我能做的就是获取所有这样的链接名称

      MyURL <- "http://stackoverflow.com/"
      MyPage <- htmlParse(MyURL) # Parse the web page
      URLroot <- xmlRoot(MyPage) # Get root node
      URL_Links_names <- xpathSApply(URLroot, "//a", xmlValue) # Get all href values
      

      这得到了我所有的链接名称。搜索名称并确定是否需要其中的部分或全部,然后您可以将链接名称传递给此函数,以根据链接名称获取每个链接的 HREF 值

      GetLinkURLByName <- function(LinkName, WebPageURL) {
        LinkURL <- getHTMLLinks(WebPageURL, xpQuery = sprintf("//a[text()='%s']/@href",LinkName))
        return(LinkURL)
      }
      

      LinkName = URL_Links_Name 中的链接名称。 WebPageURL = 您正在抓取的网页(在此示例中,我将传递 MyURL)

      【讨论】:

        猜你喜欢
        • 2018-08-01
        • 1970-01-01
        • 2020-08-08
        • 1970-01-01
        • 2020-11-17
        • 2023-03-26
        • 2018-09-13
        • 2021-05-03
        • 2017-02-27
        相关资源
        最近更新 更多