代码之家  ›  专栏  ›  技术社区  ›  Karine Mellata

序列化零散项以进行XML输出

  •  0
  • Karine Mellata  · 技术社区  · 7 年前

    <field name='example'> i have some data scraped here </field>
    

    例如,我试图找到一种添加“name”属性的方法。我知道在XmlItemExporter类中重写export\u item()方法是可能的,但我到目前为止运气不好。到目前为止,我的XmlExportPipeline看起来像这样:

    from scrapy.exporters import XmlItemExporter
    
    class XmlExportPipeline(object):
    
    def open_spider(self, spider):
        self.file = open('%s_products.xml' % spider.name, 'w+b')
        self.exporter = XmlItemExporter(self.file, item_element='field', root_element='items')
        self.exporter.start_exporting()
    
    def close_spider(self, spider):
        self.exporter.finish_exporting()
        self.file.close()
    
    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item
    

    此外,到目前为止,我的所有数据都是项目的不同字段,但理想情况下,我会将其中一些字段作为其他字段的属性。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Tarun Lalwani    7 年前

    你只需要改变 XMLItemExporter exporters.py 并添加以下代码

    import six
    from scrapy.exporters import XmlItemExporter
    from scrapy.utils.python import is_listlike
    
    class MyXmlExportPipeline(XmlItemExporter):
        def _export_xml_field(self, name, serialized_value, depth):
            self._beautify_indent(depth=depth)
            self.xg.startElement("field", {"name": name})
            if hasattr(serialized_value, 'items'):
                self._beautify_newline()
                for subname, value in serialized_value.items():
                    self._export_xml_field(subname, value, depth=depth+1)
                self._beautify_indent(depth=depth)
            elif is_listlike(serialized_value):
                self._beautify_newline()
                for value in serialized_value:
                    self._export_xml_field('value', value, depth=depth+1)
                self._beautify_indent(depth=depth)
            elif isinstance(serialized_value, six.text_type):
                self._xg_characters(serialized_value)
            else:
                self._xg_characters(str(serialized_value))
            self.xg.endElement("field")
            self._beautify_newline()
    

    我只做了两个改变

    self.xg.startElement(name, {})
    ....
    self.xg.endElement(name)
    

    从原始导出到

    self.xg.startElement("field", {"name" :name})
    ....
    self.xg.endElement("field")
    

    然后更新您的 settings.py 并添加

    FEED_EXPORTERS = {
        'xml': 'so.exporters.MyXmlExportPipeline'
    }
    

    然后我创建了一个简单的刮刀来测试输出

    class XMLExport(Spider):
        name = "xml"
    
        start_urls = ["http://www.tarunlalwani.com"]
    
        def parse(self, response):
            yield {"first_name": "tarun", "last_name": "lalwani"}
    
        pass
    

    并使用 scrapy crawl xml -o test.xml 输出XML文件为

    <?xml version="1.0" encoding="utf-8"?>
    <items>
    <item><field name="first_name">tarun</field><field name="last_name">lalwani</field></item>
    </items>