2011-03-20 62 views
2

我正在使用PyRSS2Gen,并且想要在Feed中为每个项目发布原始HTML(特别是几幅图像)。Python生成的RSS:输出原始HTML?

但是,looking at the source它似乎是RSSItem的构造函数不接受'图像',所有的HTML都是自动转义的 - 有没有什么聪明的办法可以解决这个问题?我找到了this post,但代码示例似乎不起作用。

如果任何人有更好的解决方案,我不会依附于PyRSS2Gen。也许我应该只写自己的RSS feed?

谢谢!

回答

3

我从痛苦的经历中学到了PyRSS2Gen不是为此而去的。问题是PyRSS2Gen使用python的sax库,特别是saxutility.xmlwriter,它转义了所有需要在XML中转义的字符,包括尖括号。所以即使你扩展PyRSS2Gen来添加标签,它仍然会有问题。

通常,我在RSS中看到过html(这是XML,而不是html),它包装为CDATA节。 Python的sax库没有CDATA的概念,但是minidom的确如此。所以我所做的就是放弃PyRSS2Gen,添加一些我自己的代码,并使用minidom来生成XML。

你只需要文件从minidom命名(从xml.dom.minidom进口文件)

您构建文档,如:

doc = Document() 
rss=doc.createElement('rss') 
rss.setAttribute('version', '2.0') 
doc.appendChild(rss) 
channel=doc.createElement('channel') 
rss.appendChild(channel) 
channelTitle=doc.createElement('title') 
channel.appendChild(channelTitle) 

等,然后生成XML(RSS)文件时,你完成了:

f = open('whitegrass.xml', "w") 
doc.writexml(f) 
f.close() 
+1

你的回答激发了我想写[RSS2Producer](https://github.com/nathan-osman/rss2producer ),它使用'xml.dom.minidom'生成RSS 2.0提要。这个软件包可以用'pip install rss2producer'安装。 – 2014-05-17 04:35:10

+0

弥敦道,酷!我必须检查一下。 – ViennaMike 2014-05-17 20:56:44

2

我是写你列出的博客文章的人。我从gist中复制代码,然后在安装PyRSSGen2之后,在Kubuntu 11.10下运行它,并生成没有问题的代码。看看test.xml文件,它应该看起来像这样;

<?xml version="1.0" encoding="utf-8"?> 
    <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/"> 
    <channel> 
     <title>Example Title</title> 
     <link>http://example.com</link> 
     <description>Example RSS Output</description> 
     <pubDate>Thu, 27 Oct 2011 05:36:27 GMT</pubDate> 
     <lastBuildDate>Thu, 27 Oct 2011 05:36:27 GMT</lastBuildDate> 
     <generator>PyRSS2Gen-1.0.0</generator> 
     <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

     <item> 
      <title>Item Title</title> 
      <link>http://example.com</link> 
      <media:thumbnail url="http://example.com/image.jpg"></media:thumbnail> 
      <description>< ![CDATA[<p><b>example</b>text<p><br/> 
    <p>Where are you going today?</p> 
    ]]></description> 
      <guid>random_guid_x9129319</guid> 
      <pubDate>Thu, 27 Oct 2011 14:36:27 GMT</pubDate> 
     </item> 
    </channel> 
    </rss> 

我会尽力在后面解释代码的工作原理,为了后代的缘故。

就像上面说的ViennaMike一样,PyRSS2Gen使用内置的SAX库,它会自动转义HTML。但是,有办法解决这个问题。在你提到的代码片段中,我覆盖了PyRSS2Gen的“RSSItem”,这样当它输出“description”时,它不会输出任何内容。 (这就是包含“NoOutput”类的原因)。

由于没有输出描述,我们必须添加一个方法将它附加到输出。因此,“publish_extensions”代码(输出media_thumbnail和description标签)。

我可以看到它有点令人困惑(因为你不需要media_thumbnail类),所以我已经提前并重新编写了这个类,所以没有“媒体缩略图”类可以为你解决问题。

# This is insecure, and only here for a proof of concept. Your mileage may vary. Et cetra. 
import PyRSS2Gen 
import datetime 

class NoOutput: 
    def __init__(self): 
     pass 
    def publish(self, handler): 
     pass 

class IPhoneRSS2(PyRSS2Gen.RSSItem): 
    def __init__(self, **kwargs): 
     PyRSS2Gen.RSSItem.__init__(self, **kwargs) 

    def publish(self, handler): 
     self.do_not_autooutput_description = self.description 
     self.description = NoOutput() # This disables the Py2GenRSS "Automatic" output of the description, which would be escaped. 
     PyRSS2Gen.RSSItem.publish(self, handler) 

    def publish_extensions(self, handler): 
     handler._out.write('<%s>< ![CDATA[%s]]></%s>' % ("description", self.do_not_autooutput_description, "description")) 

# How to use: 

rss = PyRSS2Gen.RSS2(
    title = "Example Title", 
    link="http://example.com", 
    description="Example RSS Output", 
    lastBuildDate=datetime.datetime.utcnow(), 
    pubDate=datetime.datetime.utcnow(), 
    items=[ 
     IPhoneRSS2(
     title="Item Title", 
     description="""<p><b>example</b>text<p><br/> 
<p>Where are you going today?</p> 

""", 
     link="http://example.com", 
     guid="random_guid_x9129319", 
     pubDate=datetime.datetime.now()), 
    ] 
) 
rss.rss_attrs["xmlns:media"] = "http://search.yahoo.com/mrss/" 
rss.write_xml(open("test.xml", "w"), "utf-8") 

您提到您要在Feed中包含图像;你是否在描述标签中包含了你的图片的HTML,还是在其他地方?如果它位于其他地方,您能否提供一个示例RSS源,以便我可以针对您的情况进行适当更改?

0

jbm的回答很好。只需一个外接起来:Python2.7.5改变萨克斯库,所以我们需要修改JBM代码:

def publish_extensions(self, handler): 
    handler._write('<%s><![CDATA[%s]]></%s>' % ("description", self.do_not_autooutput_description, "description"))