其他类型的项目可能是复杂的项目列表。当我用默认的XmlItemExporter
导出它时,子列表项的前缀是<value>
标记。如何将这些标记的值赋值给一个子标记。在
文档的项目导出页面解释了这句话:
Unless overridden in the
serialize_field()
method, multi-valued fields are exported by serializing each value inside a<value>
element. This is for convenience, as multi-valued fields are very common.
docs页面还提供了在字段中声明序列化程序和重写Serialize_Field()方法的简单示例,但这两个示例都针对单值字段,没有建议如何针对多值字段自定义它们。在
我在网上搜索了一个如何做到这一点的例子,但我没有找到任何一个。在
以下是我用于测试的项目树示例:
class Course(scrapy.Item):
title = scrapy.Field()
lessons = scrapy.Field()
class Lesson(scrapy.Item):
session = scrapy.Field()
topic = scrapy.Field()
assignment = scrapy.Field()
class ReadingAssignment(scrapy.Item):
textBook = scrapy.Field()
pages = scrapy.Field()
course = Course()
course['title'] = 'Greatness'
course['lessons'] = []
lesson = Lesson()
lesson['session'] = 'Week 1'
lesson['topic'] = 'Think Great'
lesson['assignment'] = []
reading = ReadingAssignment()
reading['textBook'] = 'Great Book 1'
reading['pages'] = '1-20'
lesson['assignment'].append(reading)
course['lessons'].append(lesson)
lesson = Lesson()
lesson['session'] = 'Week 2'
lesson['topic'] = 'Act Great'
lesson['assignment'] = []
reading = ReadingAssignment()
reading['textBook'] = 'Great Book 2'
reading['pages'] = '21-40'
lesson['assignment'].append(reading)
course['lessons'].append(lesson)
lesson = Lesson()
lesson['session'] = 'Week 3'
lesson['topic'] = 'Look Great'
lesson['assignment'] = []
reading = ReadingAssignment()
reading['textBook'] = 'Great Book 3'
reading['pages'] = '41-60'
lesson['assignment'].append(reading)
course['lessons'].append(lesson)
lesson = Lesson()
lesson['session'] = 'Week 4'
lesson['topic'] = 'Be Great'
lesson['assignment'] = []
reading = ReadingAssignment()
reading['textBook'] = 'Great Book 4'
reading['pages'] = '61-80'
lesson['assignment'].append(reading)
course['lessons'].append(lesson)
输出:
^{pr2}${1>当我完成这个任务时:
^{3}$我想做的是将这些<value>
标记更改为附加到列表中的项的名称。像这样:
<items>
<course>
<title>Greatness</title>
<lessons>
<lesson>
<session>Week 1</session>
<topic>Think Great</topic>
<assignment>
<reading>
<textBook>Great Book 1</textBook>
<pages>1-20</pages>
</reading>
</assignment>
</lesson>
<lesson>
<session>Week 2</session>
<topic>Act Great</topic>
<assignment>
<reading>
<textBook>Great Book 2</textBook>
<pages>21-40</pages>
</reading>
</assignment>
</lesson>
<lesson>
<session>Week 3</session>
<topic>Look Great</topic>
<assignment>
<reading>
<textBook>Great Book 3</textBook>
<pages>41-60</pages>
</reading>
</assignment>
</lesson>
<lesson>
<session>Week 4</session>
<topic>Be Great</topic>
<assignment>
<reading>
<textBook>Great Book 4</textBook>
<pages>61-80</pages>
</reading>
</assignment>
</lesson>
</lessons>
</course>
</items>
这确实没有很好的文档记录,我们将不得不阅读^{} source code ,结果发现} method 中:
<value>
标记选项已硬编码在^{幸运的是,有一条出路,在前面的线路上:
^{pr2}$这意味着要处理一个字典,但实际上它将接受任何具有返回字符串和项元组的
.items()
方法的任何东西!在然而,导出器中缺少一个重要步骤:递归。基本上,您只能在顶级项字段上设置} method 上都有自己的特点,因此我们不能预先处理递归,因为每个特定的导出器(JSON、XML等)在需要序列化字段的方式上各不相同。我们可以用
serializer
标志,任何超出顶级项的Field()
子类上的Field()
元素都会被当前的Scrapy实现完全忽略。每个导出器在如何驱动内部^{XmlItemExporter
类的一个子类来解决这个问题,更多信息见下文。在所以这里的第一个技巧是创建一个专用对象,该对象有一个
.items()
方法,并为您提供<container>
标记。请注意,您必须自己处理序列化的递归!垃圾序列化程序本身不处理嵌套结构的递归:然后使用
CustomXMLValuesSerializer.serialize_as()
类方法为列表字段创建自定义序列化程序:最后,我们需要一个稍微定制的导出器,它可以让我们递归地处理嵌套项:
注意,这会传入} implementation uses 。在
default_value=''
,因为that's what the base ^{请确保使用此自定义导出器,因为它在所需的上下文中传递以序列化嵌套项:
现在容器实际上是使用
name
字符串作为容器元素导出的:我用scray字段issue #3888,看看项目是否有兴趣更好地支持嵌套的
Item
结构。在另一种方法是使用对
XmlItemExporter.export_item()
方法的单独调用导出嵌套项,但这要求导出器可以作为与序列化器相同命名空间中的全局访问,或者您将导出器子类化并。。。将导出器传递给序列化程序。然后你必须满足于XmlItemExporter.export_item()
硬编码缩进。在相关问题 更多 >
编程相关推荐