Scrapy - 如何使用树结构爬网并将结构保留在输出的Json文件中

时间:2016-05-24 12:27:30

标签: python json tree scrapy

我正在尝试抓取一个具有树结构的网站,我想在输出的json文件中重新创建该树结构。

所有页面都具有相同的结构,我必须从页面获取一些字段,而不是转到每个链接的子页面并获取相同的字段等...

json文件中的项目输出如下所示(这是简化的):

{"Organiation": [{"Administration": "name_adm", 
                  "Rattachement": ["ratt_a", "ratt_b"],
                  "Organiation": [{"Administration": "name_adm", 
                                   "Rattachement": ["ratt_a", "ratt_b"],
                                   "Organiation": [{"Administration": "name_adm",
                                                    "Rattachement": ["ratt_a", "ratt_b"],
                                                    "Organiation": [null]
                                     }],
                                   "Organiation": [{"Administration": "name_adm",
                                                    "Rattachement": ["ratt_a", "ratt_b"],
                                                    "Organiation": [{"Administration": "name_adm",
                                                                     "Rattachement":["ratt_a", "ratt_b"],
                                                                     "Organiation": [null]
                                                 }]
                                     }]
                        }]
            }]
}

我能够做到的是每页获得一个项目:

{"Organiation": [{"Administration": "name_adm", "Rattachement": ["ratt_a", "ratt_b"], "Organisation" = ["orga1", "orga2", ...]]}
{"Organiation": [{"Administration": "name_adm", "Rattachement": ["ratt_a", "ratt_b"], "Organisation" = ["orga1", "orga2", ...]]}
etc...

我花了很多时间试图找到一种方法,但没有成功,我探索了递归选项,但我无法使其工作主要是因为我现在不知道如何递归解析使用“回调”(请参阅​​下面的代码了解解析函数)。

这是我到目前为止所得到的:

def parse(self, response):
    for url in response.xpath('//ul[@class = "list-arrow list-narrow"]/li/a/@href').extract():
        yield scrapy.Request(url, callback=self.parse_dir_contents)

def parse_dir_contents(self, response):
    page = PageItem()  

    page['Administration'] = response.xpath('//div[@class = "panel-body"]/p/span/text()' ).extract()

    Rattachements = []        
    for site in response.xpath('//ul[@class ="list-connected"]/li'):
        Rattachements.append(site.xpath('a/text()').extract())
    page['Rattachement'] = Rattachements

    Organisations = [] 
    for site in response.xpath('//ul[@data-test="organizations"]/li/a'):
        Organisations.append(site.xpath('text()').extract())
    page['Organisation'] = Organisations
    yield page

    URLS = response.xpath('//ul[@data-test="organizations"]/li/a/@href').extract()
    for url in URLS:
        yield scrapy.Request(url, callback=self.parse_dir_contents)

最后一段代码允许我将每个页面放在一个项目中:

    URLS = response.xpath('//ul[@data-test="organizations"]/li/a/@href').extract()
    for url in URLS:
        yield scrapy.Request(url, callback=self.parse_dir_contents)

URLS是指向给定页面的下一级子页面的链接。

当我无法获得树结构时,接下来最好的想法是将“组织”放入子页面链接的文本列表中,但如果我可以获得树结构,我将不需要将此列表保留在“组织”中。

我如何更改代码,以便将网站的树结构保留在Json输出中。

由于

2 个答案:

答案 0 :(得分:0)

尝试使用jsonmerge jsonmerge包将您当前的输出合并在一起。

当所有合并完成后返回项目,您可以使用空闲处理程序来实现它。

答案 1 :(得分:0)

您可以通过在Spider中创建一个实例变量,然后在解析函数中向其中添加数据来实现此目的。最后,在所有抓取完成之后,您可以将数据返回到Scrapy框架以进行输出。

This spider是一个有效的示例。