如何使用Python从网站中提取RSS链接

tag*_*aga 5 python rss beautifulsoup web-scraping

我正在尝试从某些网站提取所有 RSS 提要链接。Ofc(如果 RSS 存在)。这些是一些具有 RSS 的网站链接,下面是这些网站的 RSS 链接列表。

website_links = ["https://www.diepresse.com/", 
"https://www.sueddeutsche.de/", 
"https://www.berliner-zeitung.de/", 
"https://www.aargauerzeitung.ch/", 
"https://www.luzernerzeitung.ch/", 
"https://www.nzz.ch/",
"https://www.spiegel.de/", 
"https://www.blick.ch/",
"https://www.berliner-zeitung.de/", 
"https://www.ostsee-zeitung.de/", 
"https://www.kleinezeitung.at/", 
"https://www.blick.ch/", 
"https://www.ksta.de/", 
"https://www.tagblatt.ch/", 
"https://www.srf.ch/", 
"https://www.derstandard.at/"]


website_rss_links = ["https://www.diepresse.com/rss/Kunst", 
"https://rss.sueddeutsche.de/rss/Kultur", 
"https://www.berliner-zeitung.de/feed.id_kultur-kunst.xml", 
"https://www.aargauerzeitung.ch/leben-kultur.rss", 
"https://www.luzernerzeitung.ch/kultur.rss", 
"https://www.nzz.ch/technologie.rss", 
"https://www.spiegel.de/kultur/literatur/index.rss", 
"https://www.luzernerzeitung.ch/wirtschaft.rss", 
"https://www.blick.ch/wirtschaft/rss.xml", 
"https://www.berliner-zeitung.de/feed.id_abgeordnetenhauswahl.xml", 
"https://www.ostsee-zeitung.de/arc/outboundfeeds/rss/category/wissen/", 
"https://www.kleinezeitung.at/rss/politik", 
"https://www.blick.ch/wirtschaft/rss.xml", 
"https://feed.ksta.de/feed/rss/politik/index.rss", 
"https://www.tagblatt.ch/wirtschaft.rss", 
"https://www.srf.ch/news/bnf/rss/1926", 
"https://www.derstandard.at/rss/wirtschaft"]
Run Code Online (Sandbox Code Playgroud)

我的方法是提取所有链接,然后检查其中一些链接是否包含 RSS,但这只是第一步:

for url in all_links:
    
    response = requests.get(url)
    print(response)
    soup = BeautifulSoup(response.content, 'html.parser')
    list_of_links = soup.select("a[href]")
    list_of_links = [link["href"] for link in list_of_links]
    print("Number of links", len(list_of_links))
 

    for l in list_of_links:
        if "rss" in l:
            print(url)
            print(l)
    print()
    
Run Code Online (Sandbox Code Playgroud)

我听说我可以查找这样的 RSS 链接,但我不知道如何将其合并到我的代码中。

type=application/rss+xml
Run Code Online (Sandbox Code Playgroud)

我的目标是最终获得有效的 RSS 网址。也许这是一个问题,因为我在第一页上发送请求,也许我应该抓取不同的页面以提取所有 RSS 链接,但我希望有一种更快/更好的 RSS 提取方法。

您可以看到 RSS 链接具有或结束于(例如):

.rss
/rss
/rss/
rss.xml
/feed/
rss-feed
Run Code Online (Sandbox Code Playgroud)

ETC。

Hed*_*Hog 8

不要重新发明轮子,有许多精选的目录和集合可以很好地为您服务并为您提供很好的介绍。

但是,要遵循您的方法,您应该首先收集页面上可能指向 rss feed 的所有链接:

soup.select('a[href*="rss"],a[href*="/feed"],a:-soup-contains-own("RSS")')
Run Code Online (Sandbox Code Playgroud)

然后再次验证它是一个还是只是一个集合页面:

soup.select('[type="application/rss+xml"],a[href*=".rss"]')
Run Code Online (Sandbox Code Playgroud)

或检查content-type

if 'xml' in requests.get(rss).headers.get('content-type'):
Run Code Online (Sandbox Code Playgroud)

注意: 这只是指向一个方向,因为有很多模式用于标记此类提要 - rss、feed、feed/、news、xml...并且content-type服务器提供的方式也不同

例子

import requests, re
from bs4 import BeautifulSoup

website_links = ["https://www.diepresse.com/", 
"https://www.sueddeutsche.de/", 
"https://www.berliner-zeitung.de/", 
"https://www.aargauerzeitung.ch/", 
"https://www.luzernerzeitung.ch/", 
"https://www.nzz.ch/technologie/",
"https://www.spiegel.de/", 
"https://www.blick.ch/wirtschaft/"]

rss_feeds = []

def check_for_real_rss(url):
    base_url = re.search('^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)',url).group(0)
    r = requests.get(url)
    soup = BeautifulSoup(r.text)
    for e in soup.select('[type="application/rss+xml"],a[href*=".rss"],a[href$="feed"]'):
        if e.get('href').startswith('/'):
            rss = (base_url+e.get('href'))
        else:
            rss = (e.get('href'))
        if 'xml' in requests.get(rss).headers.get('content-type'):
            rss_feeds.append(rss)

for url in website_links:
    soup = BeautifulSoup(requests.get(url).text)
    for e in soup.select('a[href*="rss"],a[href*="/feed"],a:-soup-contains-own("RSS")'):
        if e.get('href').startswith('/'):
            check_for_real_rss(url.strip('/')+e.get('href'))
        else:
            check_for_real_rss(e.get('href'))
set(rss_feeds)
Run Code Online (Sandbox Code Playgroud)

输出

{'https://rss.sueddeutsche.de/app/service/rss/alles/index.rss?output=rss','https://rss.sueddeutsche.de/rss/Topthemen',
 'https://www.aargauerzeitung.ch/aargau/aarau.rss',
 'https://www.aargauerzeitung.ch/aargau/baden.rss',
 'https://www.aargauerzeitung.ch/leben-kultur.rss',
 'https://www.aargauerzeitung.ch/schweiz-welt.rss',
 'https://www.aargauerzeitung.ch/sport.rss',
 'https://www.bzbasel.ch/basel.rss',
 'https://www.grenchnertagblatt.ch/solothurn/grenchen.rss',
 'https://www.jetzt.de/alle_artikel.rss',
 'https://www.limmattalerzeitung.ch/limmattal.rss',
 'https://www.luzernerzeitung.ch/international.rss',
 'https://www.luzernerzeitung.ch/kultur.rss',
 'https://www.luzernerzeitung.ch/leben.rss',
 'https://www.luzernerzeitung.ch/leben/ratgeber.rss',...}
Run Code Online (Sandbox Code Playgroud)