【问题标题】:Cannot extract links from RSS feed using Rvest package无法使用 Rvest 包从 RSS 提要中提取链接
【发布时间】:2019-10-22 18:35:36
【问题描述】:

我正在尝试从 RSS 提要获取 WSJ 文章的链接。

Feed 如下所示:

<rss xmlns:wsj="http://dowjones.net/rss/" xmlns:dj="http://dowjones.net/rss/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>WSJ.com: World News</title>
<link>http://online.wsj.com/page/2_0006.html</link>
<atom:link type="application/rss+xml" rel="self" href="http://online.wsj.com/page/2_0006.html"/>
<description>World News</description>
<language>en-us</language>
<pubDate>Mon, 09 Sep 2019 10:56:42 -0400</pubDate>
<lastBuildDate>Mon, 09 Sep 2019 10:56:42 -0400</lastBuildDate>
<copyright>Dow Jones & Company, Inc.</copyright>
<generator>http://online.wsj.com/page/2_0006.html</generator>
<docs>http://cyber.law.harvard.edu/rss/rss.html</docs>
<image>
<title>WSJ.com: World News</title>
<link>http://online.wsj.com/page/2_0006.html</link>
<url>http://online.wsj.com/img/wsj_sm_logo.gif</url>
</image>
<item>
<title>
Boris Johnson Promises Oct. 31 Brexit as Law Passes to Rule Out No Deal
</title>
<link>
https://www.wsj.com/articles/boris-johnson-insists-he-wants-a-brexit-deal-despite-no-deal-planning-11568037248
</link>
<description>
<![CDATA[
British Prime Minister Boris Johnson stuck to his pledge that the U.K. would leave the European Union on Oct. 31—even as a bill aimed at preventing the country from leaving on that date without an agreement became law.
]]>
</description>
<content:encoded/>
<pubDate>Mon, 09 Sep 2019 10:46:00 -0400</pubDate>
<guid isPermaLink="false">SB10710731395272083797004585540162284821560</guid>
<category domain="AccessClassName">PAID</category>
<wsj:articletype>U.K. News</wsj:articletype>
</item>
<item>
<title>
Russian Opposition Puts Putin Under Pressure in Moscow Election
</title>
<link>
https://www.wsj.com/articles/russian-opposition-puts-putin-under-pressure-in-moscow-election-11568029495
</link>
<description>
<![CDATA[
Candidates backed by Russia’s opposition won nearly half the seats up for grabs in Moscow’s city elections Sunday, building on a wave of protests that exposed some of the frailties in President Putin’s closely controlled political machine, but failed to make significant inroads in local races elsewhere.
]]>
</description>
<content:encoded/>
<pubDate>Mon, 09 Sep 2019 07:44:00 -0400</pubDate>
<guid isPermaLink="false">SB10710731395272083797004585539862964447000</guid>
<category domain="AccessClassName">PAID</category>
<wsj:articletype>Russia News</wsj:articletype>
</item>

我一直在使用rvest 来获取每篇文章的标题,这很有效,但链接每次都返回空白。我用几种不同的方式尝试了代码,但这是最近的尝试:


rm(list=ls())
library(tidyverse)
library(rvest)
setwd("~/wsj/world_news")

wsj_1 <- "wsj-world_news-1568041806.39885.xml" # a file like the example one provided above

test <- wsj_1 %>% read_html() # reading in example file

items <- wsj_1 %>%
  read_html() %>%
  html_nodes('item') # parsing the xml to get each 'item' which is a separate article

title <- items %>% 
  html_nodes('title') %>% 
  html_text()

link <- items %>% 
  html_node('link') %>% 
  html_text()

知道为什么我无法显示链接吗?我得到&lt;link&gt; 而不是网址。

我也无法提取描述标签中的 CDATA 文本,但这不是我最关心的问题。如果我能得到链接就足够了。

【问题讨论】:

    标签: r xml web-scraping rss rvest


    【解决方案1】:

    如果没有您使用的确切完整的 rss 提要,我将四处走动,并采用与我能找到的 rss 提要类似的风格。如果您查看输出 html,您会看到这些链接实际上是下一个兄弟,因此您可以使用 xpath 并指定为 following-sibling。我使用 purrr 生成数据帧并使用 str_squish 对输出进行一些清理


    R:

    library(rvest)
    library(tidyverse)
    library(stringr)
    
    wsj_1 <- 'https://feeds.a.dj.com/rss/RSSWorldNews.xml'
    nodes <- wsj_1%>%read_html()%>%html_nodes('item')
    
    df <- map_df(nodes, function(item) {
    
      data.frame(title = str_squish(item%>%html_node('title') %>% html_text()),
                 link = str_squish(item%>%html_node(xpath="*/following-sibling::text()") %>%
                        html_text()),
                 stringsAsFactors=FALSE)
    })
    


    派:

    import requests, re
    from bs4 import BeautifulSoup as bs
    import pandas as pd
    
    r = requests.get('https://feeds.a.dj.com/rss/RSSWorldNews.xml')
    soup = bs(r.content, 'lxml')
    titles = []; links = [] 
    
    for i in soup.select('item'):
        titles+=[re.sub(r'\n+\s+\t+',' ',i.title.text.strip())]
        links+=[i.link.next_sibling]
    
    df = pd.DataFrame(zip(titles, links), columns = ['Title', 'Link'])
    print(df)
    

    【讨论】:

    • 如果此解决方案不适用于您的确切场景,请提供完整的供稿 URI 以供测试。
    • 谢谢,是的,这似乎解决了我的问题。您使用该提要是正确的。作为示例,我只是在我的问题中发布了一个较短、较旧的版本。下一个兄弟是否意味着我感兴趣的文本实际上出现在 的末尾?我不知道这一点并检查了html代码。感谢您指出这一点。
    • 是的。它位于链接结束标记之后。 developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling
    猜你喜欢
    • 2015-11-03
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2016-05-16
    • 1970-01-01
    • 2018-11-19
    • 2017-10-11
    相关资源
    最近更新 更多