文章目录
- 一、关于 feedparser
- 二、安装
- 三、关于文档及构建
- 四、测试
- 五、常见RSS元素
- 访问常见 Channel 元素
- 访问常用项目元素
- 六、常见Atom元素
- 访问常用feed元素
- 访问公共入口元素
- 七、获取Atom元素的详细信息
- Feed元素的详细信息
- 八、测试元素是否存在
- 九、其他功能 & 文档
- 高级功能
- HTTP特性
- 十、Reference
一、关于 feedparser
- github : https://github.com/kurtmckee/feedparser
- 文档:https://feedparser.readthedocs.io/en/latest/
在Python中解析Atom和RSSfeed。
二、安装
可以通过运行pip来安装:
pip install feedparser
三、关于文档及构建
feedparser 文档 :https://feedparser.readthedocs.io/en/latest/
它还包含在docs/目录中的源格式 ReST中。
要构建文档,您需要Sphinx包,下载地址:https://www.sphinx-doc.org/
然后,您可以使用类似于以下命令,构建 HTML 页面:
sphinx-build -b html docs/ fpdocs
这将在fpdocs/目录中,产生HTML文档。
四、测试
Feedparser 有一个广泛的测试套件,由Tox提供支持。要运行它,请键入以下内容:
$ python -m venv venv
$ source venv/bin/activate # or "venv\bin\activate.ps1" on Windows
(venv) $ python -m pip install --upgrade pip
(venv) $ python -m pip install tox
(venv) $ tox
五、常见RSS元素
RSS feeds 中最常用的元素(无论版本如何)是标题、链接、描述、发布日期和条目ID。发布日期来自 pubDate 元素,条目ID 来自guid元素。
此示例RSSfeed位于 https://feedparser.readthedocs.io/en/latest/examples/rss20.xml。
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Sample Feed</title>
<description>For documentation <em>only</em></description>
<link>http://example.org/</link>
<pubDate>Sat, 07 Sep 2002 00:00:01 GMT</pubDate>
<!-- other elements omitted from this example -->
<item>
<title>First entry title</title>
<link>http://example.org/entry/3</link>
<description>Watch out for <span style="background-image:
url(javascript:window.location='http://example.org/')">nasty
tricks</span></description>
<pubDate>Thu, 05 Sep 2002 00:00:01 GMT</pubDate>
<guid>http://example.org/entry/3</guid>
<!-- other elements omitted from this example -->
</item>
</channel>
</rss>
通道元素在d.feed中可用。
访问常见 Channel 元素
>>> import feedparser
>>> d = feedparser.parse('https://feedparser.readthedocs.io/en/latest/examples/rss20.xml')
>>> d.feed.title
'Sample Feed'
>>> d.feed.link
'http://example.org/'
>>> d.feed.description
'For documentation <em>only</em>'
>>> d.feed.published
'Sat, 07 Sep 2002 00:00:01 GMT'
>>> d.feed.published_parsed
(2002, 9, 7, 0, 0, 1, 5, 250, 0)
d.entries中的这些项目可用,这是一个列表。
您可以按照它们在原始feed中出现的顺序 访问列表中的项目,因此在d.entries[0]中的第一个项目可用。
访问常用项目元素
>>> import feedparser
>>> d = feedparser.parse('https://feedparser.readthedocs.io/en/latest/examples/rss20.xml')
>>> d.entries[0].title
'First item title'
>>> d.entries[0].link
'http://example.org/item/1'
>>> d.entries[0].description
'Watch out for <span>nasty tricks</span>'
>>> d.entries[0].published
'Thu, 05 Sep 2002 00:00:01 GMT'
>>> d.entries[0].published_parsed
(2002, 9, 5, 0, 0, 1, 3, 248, 0)
>>> d.entries[0].id
'http://example.org/guid/1'
注:您还可以使用Atom术语 从RSSfeed访问数据。有关详细信息,请参阅 Content Normalization 。
六、常见Atom元素
Atomfeed通常比RSSfeed包含更多信息(因为需要更多元素),但最常用的元素仍然是标题、链接、副标题/描述、各种日期和ID。
此示例Atomfeed https://feedparser.readthedocs.io/en/latest/examples/atom10.xml 。
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xml:base="http://example.org/"
xml:lang="en">
<title type="text">Sample Feed</title>
<subtitle type="html">
For documentation <em>only</em>
</subtitle>
<link rel="alternate" href="/"/>
<link rel="self"
type="application/atom+xml"
href="http://www.example.org/atom10.xml"/>
<rights type="html">
<p>Copyright 2005, Mark Pilgrim</p><
</rights>
<id>tag:feedparser.org,2005-11-09:/docs/examples/atom10.xml</id>
<generator
uri="http://example.org/generator/"
version="4.0">
Sample Toolkit
</generator>
<updated>2005-11-09T11:56:34Z</updated>
<entry>
<title>First entry title</title>
<link rel="alternate"
href="/entry/3"/>
<link rel="related"
type="text/html"
href="http://search.example.com/"/>
<link rel="via"
type="text/html"
href="http://toby.example.com/examples/atom10"/>
<link rel="enclosure"
type="video/mpeg4"
href="http://www.example.com/movie.mp4"
length="42301"/>
<id>tag:feedparser.org,2005-11-09:/docs/examples/atom10.xml:3</id>
<published>2005-11-09T00:23:47Z</published>
<updated>2005-11-09T11:56:34Z</updated>
<summary type="text/plain" mode="escaped">Watch out for nasty tricks</summary>
<content type="application/xhtml+xml" mode="xml"
xml:base="http://example.org/entry/3" xml:lang="en-US">
<div xmlns="http://www.w3.org/1999/xhtml">Watch out for
<span style="background: url(javascript:window.location='http://example.org/')">
nasty tricks</span></div>
</content>
</entry>
</feed>
feed 元素在d.feed中可用。
访问常用feed元素
>>> import feedparser
>>> d = feedparser.parse('https://feedparser.readthedocs.io/en/latest/examples/atom10.xml')
>>> d.feed.title
'Sample feed'
>>> d.feed.link
'http://example.org/'
>>> d.feed.subtitle
'For documentation <em>only</em>'
>>> d.feed.updated
'2005-11-09T11:56:34Z'
>>> d.feed.updated_parsed
(2005, 11, 9, 11, 56, 34, 2, 313, 0)
>>> d.feed.id
'tag:feedparser.org,2005-11-09:/docs/examples/atom10.xml'
条目在d.entries中可用,这是一个列表。
您可以在 它们在原始feed中出现的顺序,因此第一个条目是 d.entries[0]。
访问公共入口元素
>>> import feedparser
>>> d = feedparser.parse('https://feedparser.readthedocs.io/en/latest/examples/atom10.xml')
>>> d.entries[0].title
'First entry title'
>>> d.entries[0].link
'http://example.org/entry/3
>>> d.entries[0].id
'tag:feedparser.org,2005-11-09:/docs/examples/atom10.xml:3'
>>> d.entries[0].published
'2005-11-09T00:23:47Z'
>>> d.entries[0].published_parsed
(2005, 11, 9, 0, 23, 47, 2, 313, 0)
>>> d.entries[0].updated
'2005-11-09T11:56:34Z'
>>> d.entries[0].updated_parsed
(2005, 11, 9, 11, 56, 34, 2, 313, 0)
>>> d.entries[0].summary
'Watch out for nasty tricks'
>>> d.entries[0].content
[{'type': 'application/xhtml+xml',
'base': 'http://example.org/entry/3',
'language': 'en-US',
'value': '<div>Watch out for <span>nasty tricks</span></div>'}]
注:解析后的摘要和内容 与它们出现在 原始feed 不用。原始元素包含危险的超文本标记语言标记,已被清理。详见 Sanitization 。
因为Atom条目可以有多个内容元素, d.entries[0].content是字典的列表。
每个字典包含 关于单个内容元素的元信息。
字典中最重要的两个值是 内容类型(在d.entries[0].content[0].type中)和 实际内容值(在d.entries[0].content[0].value中)。
您也可以在其他Atom元素上获得此详细级别。
七、获取Atom元素的详细信息
几个Atom元素共享Atom内容模型:标题、副标题、权利、摘要,当然还有内容。(Atom 0.3也有一个共享此内容模型的info元素。)
通用Feed Parser 捕获关于这些元素的所有相关元信息,最重要的是体裁和值本身。
Feed元素的详细信息
>>> import feedparser
>>> d = feedparser.parse('https://feedparser.readthedocs.io/en/latest/examples/atom10.xml')
>>> d.feed.title_detail
{'type': 'text/plain',
'base': 'http://example.org/',
'language': 'en',
'value': 'Sample Feed'}
>>> d.feed.subtitle_detail
{'type': 'text/html',
'base': 'http://example.org/',
'language': 'en',
'value': 'For documentation <em>only</em>'}
>>> d.feed.rights_detail
{'type': 'text/html',
'base': 'http://example.org/',
'language': 'en',
'value': '<p>Copyright 2004, Mark Pilgrim</p>'}
>>> d.entries[0].title_detail
{'type': 'text/plain',
'base': 'http://example.org/',
'language': 'en',
'value': 'First entry title'}
>>> d.entries[0].summary_detail
{'type': 'text/plain',
'base': 'http://example.org/',
'language': 'en',
'value': 'Watch out for nasty tricks'}
>>> len(d.entries[0].content)
1
>>> d.entries[0].content[0]
{'type': 'application/xhtml+xml',
'base': 'http://example.org/entry/3',
'language': 'en-US'
'value': '<div>Watch out for <span> nasty tricks</span></div>'}
八、测试元素是否存在
现实世界中的Feeds可能缺少元素,甚至是规范要求的元素。
在获取元素值之前,您应该始终测试元素的存在。永远不要假设元素存在。
要测试元素是否存在,可以使用标准Python字典习语。
>>> import feedparser
>>> d = feedparser.parse('https://feedparser.readthedocs.io/en/latest/examples/atom10.xml')
>>> 'title' in d.feed
True
>>> 'ttl' in d.feed
False
>>> d.feed.get('title', 'No title')
'Sample feed'
>>> d.feed.get('ttl', 60)
60
九、其他功能 & 文档
高级功能
- 日期解析
- 日期格式的历史
- 识别日期格式
- 支持其他日期格式
- Sanitization
- HTML Sanitization
- SVG Sanitization
- MathML Sanitization
- CSS Sanitization
- 列入白名单,不要列入黑名单
- 内容标准化
- 将Atom feed 作为RSS feed 访问
- 将RSS feed 作为Atom feed 访问
- 命名空间处理
- 访问命名空间元素
- 使用非标准前缀 访问命名空间元素
- Relative Link Resolution
- 哪些值是URI
- 如何解决相对URI
- 禁用相对URI解析
- Feed Type and Version Detection feed类型和版本检测
- 访问feed版本
- 字符编码检测
- 字符编码简介
- 处理 Incorrectly-Declared 编码
- 处理 Incorrectly-Declared 媒体类型
- Bozo 检测
- 检测格式不正确的反馈
HTTP特性
- ETag 和最后修改的头文件
- 使用ETags减少带宽
- 使用Last-Modified 头文件来减少带宽
- User-Agent和Referer 头文件
- 自定义 User-Agent
- 永久自定义 User-Agent
- 自定义 referrer
- HTTP重定向
- 注意临时重定向
- 注意永久重定向
- 注意标记为“gone”的feeds
- 受密码保护的feed
- 下载 受基本鉴权保护 的 feed(简单方法)
- 下载 受摘要鉴权保护的feed(简单但非常不安全的方式)
- 下载受HTTP基本鉴权保护的feed(硬方法)
- 下载受HTTP摘要鉴权保护的feed(安全方式)
- 确定feed受密码保护
- 其他HTTP 头文件
- 发送自定义HTTP请求 头文件
- 访问其他HTTP响应 头文件
十、Reference
bozobozo_exceptionencodingentriesentries[i\].authorentries[i].author_detailentries[i\].author_detail.nameentries[i\].author_detail.hrefentries[i\].author_detail.email
entries[i\].commentsentries[i].contententries[i\].content[j].valueentries[i\].content[j].typeentries[i\].content[j].languageentries[i\].content[j].base
entries[i].contributorsentries[i\].contributors[j].nameentries[i\].contributors[j].hrefentries[i\].contributors[j].email
entries[i\].createdentries[i\].created_parsedentries[i].enclosuresentries[i\].enclosures[j].hrefentries[i\].enclosures[j].lengthentries[i\].enclosures[j].type
entries[i\].expiredentries[i\].expired_parsedentries[i\].identries[i\].licenseentries[i\].linkentries[i].linksentries[i\].links[j].relentries[i\].links[j].typeentries[i\].links[j].hrefentries[i\].links[j].title
entries[i\].publishedentries[i\].published_parsedentries[i\].publisherentries[i].publisher_detailentries[i\].publisher_detail.nameentries[i\].publisher_detail.hrefentries[i\].publisher_detail.email
entries[i].sourceentries[i\].source.authorentries[i\].source.author_detailentries[i\].source.contributorsentries[i\].source.iconentries[i\].source.identries[i\].source.linkentries[i\].source.linksentries[i\].source.logoentries[i\].source.rightsentries[i\].source.rights_detailentries[i\].source.subtitleentries[i\].source.subtitle_detailentries[i\].source.titleentries[i\].source.title_detailentries[i\].source.updatedentries[i\].source.updated_parsed
entries[i\].summaryentries[i].summary_detailentries[i\].summary_detail.valueentries[i\].summary_detail.typeentries[i\].summary_detail.languageentries[i\].summary_detail.base
entries[i].tagsentries[i\].tags[j].termentries[i\].tags[j].schemeentries[i\].tags[j].label
entries[i\].titleentries[i].title_detailentries[i\].title_detail.valueentries[i\].title_detail.typeentries[i\].title_detail.languageentries[i\].title_detail.base
entries[i\].updatedentries[i\].updated_parsedetagfeedfeed.authorfeed.author_detailfeed.author_detail.namefeed.author_detail.hreffeed.author_detail.email
feed.cloudfeed.cloud.domainfeed.cloud.portfeed.cloud.pathfeed.cloud.registerProcedurefeed.cloud.protocol
feed.contributorsfeed.contributors[i\].namefeed.contributors[i\].hreffeed.contributors[i\].email
feed.docsfeed.errorreportstofeed.generatorfeed.generator_detailfeed.generator_detail.namefeed.generator_detail.hreffeed.generator_detail.version
feed.iconfeed.idfeed.imagefeed.image.titlefeed.image.hreffeed.image.linkfeed.image.widthfeed.image.heightfeed.image.description
feed.infofeed.info_detailfeed.info_detail.valuefeed.info_detail.typefeed.info_detail.languagefeed.info_detail.base
feed.languagefeed.licensefeed.linkfeed.linksfeed.links[i\].relfeed.links[i\].typefeed.links[i\].hreffeed.links[i\].title
feed.logofeed.publishedfeed.published_parsedfeed.publisherfeed.publisher_detailfeed.publisher_detail.namefeed.publisher_detail.hreffeed.publisher_detail.email
feed.rightsfeed.rights_detailfeed.rights_detail.valuefeed.rights_detail.typefeed.rights_detail.languagefeed.rights_detail.base
feed.subtitlefeed.subtitle_detailfeed.subtitle_detail.valuefeed.subtitle_detail.typefeed.subtitle_detail.languagefeed.subtitle_detail.base
feed.tagsfeed.tags[i\].termfeed.tags[i\].schemefeed.tags[i\].label
feed.textinputfeed.textinput.titlefeed.textinput.linkfeed.textinput.namefeed.textinput.description
feed.titlefeed.title_detailfeed.title_detail.valuefeed.title_detail.typefeed.title_detail.languagefeed.title_detail.base
feed.ttlfeed.updatedfeed.updated_parsedheadershrefmodifiednamespacesstatusversion
2024-06-07(五)
