Сгенерированный Python RSS: вывод необработанного HTML? - PullRequest
2 голосов
/ 21 марта 2011

Я использую PyRSS2Gen и хочу опубликовать сырой HTML (в частности, пару изображений) с каждым элементом в моем фиде.

Однако, глядя на источник кажется, что конструктор для RSSItem не принимает 'изображение', и весь HTML автоматически экранирован - есть ли какой-нибудь умный способ обойти это?

Я нашел этот пост , но пример кода не работает.

Я не привязан к PyRSS2Gen, если у кого-то есть лучшее решение. Может, мне просто написать свой собственный канал RSS?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 23 марта 2011

Я узнал из мучительного опыта, что PyRSS2Gen - не лучший способ для этого.Проблема в том, что PyRSS2Gen использует библиотеку саксофонов python, в частности saxutility.xmlwriter, которая экранирует все символы, которые необходимо экранировать в XML, включая угловые скобки.Так что даже если вы расширите PyRSS2Gen для добавления тега, у него все равно будет проблема.

Как правило, я видел html в RSS (который представляет собой XML, а не html), заключенный в раздел CDATA.Саксофонная библиотека Python не имеет понятия CDATA, но минидом имеет.Поэтому я удалил PyRSS2Gen, добавил несколько дополнительных строк моего собственного кода и использовал minidom для генерации XML.

Вам нужен только документ из minidom (из xml.dom.minidom import Document)

Вы создаете документ следующим образом:

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()
2 голосов
/ 27 октября 2011

Я был человеком, который написал пост в блоге, который вы перечислили. Я скопировал код из сущности и просто запустил его под Kubuntu 11.10, после установки PyRSSGen2, и без проблем создал код. Посмотрите в файле 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. Однако есть способы обойти это. Во фрагменте кода, который вы упомянули, я переопределил «RSSItem» PyRSS2Gen, чтобы при выводе «description» он ничего не выводил. (Это было то, что стояло за включением класса "NoOutput").

Поскольку описание не выводится, мы должны добавить метод, чтобы присоединить его к выводу самостоятельно. Следовательно, код "publish_extensions" (который выводит теги media_thumbnail и description).

Я вижу, что это несколько сбивает с толку (поскольку вам не нужен класс media_thumbnail), поэтому я решил переписать этот класс, чтобы не было класса "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")

Вы упоминаете, что хотите включить изображение в свой канал; Вы включаете HTML-код изображения в тег описания или в другом месте? Если это где-то еще, можете ли вы предоставить образец RSS-канала, чтобы я мог внести соответствующие изменения в вашу ситуацию?

0 голосов
/ 20 апреля 2014

JBM ответ хороший. Просто дополнение: Python2.7.5 изменил библиотеку sax, поэтому нам нужно изменить код jbm:

def publish_extensions(self, handler):
    handler._write('<%s><![CDATA[%s]]></%s>' % ("description", self.do_not_autooutput_description, "description"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...