2017-08-04 2 views
1

Ich bin scraping Auflistungen mit Scrapy. Mein Skript analysiert zunächst die Listen-URLs mit parse_node. Anschließend analysiert es jeden Eintrag unter Verwendung von parse_listing. Für jeden Eintrag analysiert er die Agenten für den Eintrag unter Verwendung von parse_agent. Ich möchte ein Array erstellen, das sich als Scrapy-Parser durch die Listings und die Agenten für die Listings aufbaut und für jeden neuen Listing zurücksetzt.Erstellen Scrapy Array von Elementen mit mehreren Parse

Hier ist meine Analyse Skript:

def parse_node(self,response,node): 
    yield Request('LISTING LINK',callback=self.parse_listing) 
def parse_listing(self,response): 
    yield response.xpath('//node[@id="ListingId"]/text()').extract_first() 
    yield response.xpath('//node[@id="ListingTitle"]/text()').extract_first() 
    for agent in string.split(response.xpath('//node[@id="Agents"]/text()').extract_first() or "",'^'): 
    yield Request('AGENT LINK',callback=self.parse_agent) 
def parse_agent(self,response): 
    yield response.xpath('//node[@id="AgentName"]/text()').extract_first() 
    yield response.xpath('//node[@id="AgentEmail"]/text()').extract_first() 

Ich möchte in parse_listing führen:

{ 
'id':123, 
'title':'Amazing Listing' 
} 

dann auf die Kotierung Array hinzufügen parse_agent:

{ 
'id':123, 
'title':'Amazing Listing' 
'agent':[ 
    { 
    'name':'jon doe', 
    'email:'[email protected]' 
    }, 
    { 
    'name':'jane doe', 
    'email:'[email protected]' 
    } 
] 
} 

Wie Ich bekomme die Ergebnisse von jedem Level und baue ein Array auf?

Antwort

3

Diese etwas kompliziert ausgestellt:
Sie benötigen ein einzelnes Element aus mehreren verschiedenen URLs zu bilden.

Scrapy können Sie über Daten in Wunsch des Metaattribut tragen, so dass Sie so etwas wie tun:

def parse_node(self,response,node): 
    yield Request('LISTING LINK', callback=self.parse_listing) 

def parse_listing(self,response): 
    item = defaultdict(list) 
    item['id'] = response.xpath('//node[@id="ListingId"]/text()').extract_first() 
    item['title'] = response.xpath('//node[@id="ListingTitle"]/text()').extract_first() 
    agent_urls = string.split(response.xpath('//node[@id="Agents"]/text()').extract_first() or "",'^') 
    # find all agent urls and start with first one 
    url = agent_urls.pop(0) 
    # we want to go through agent urls one-by-one and update single item with agent data 
    yield Request(url, callback=self.parse_agent, 
        meta={'item': item, 'agent_urls' agent_urls}) 

def parse_agent(self,response): 
    item = response.meta['item'] # retrieve item generated in previous request 
    agent = dict() 
    agent['name'] = response.xpath('//node[@id="AgentName"]/text()').extract_first() 
    agent['email'] = response.xpath('//node[@id="AgentEmail"]/text()').extract_first() 
    item['agents'].append(agent) 
    # check if we have any more agent urls left 
    agent_urls = response.meta['agent_urls'] 
    if not agent_urls: # we crawled all of the agents! 
     return item 
    # if we do - crawl next agent and carry over our current item 
    url = agent_urls.pop(0) 
    yield Request(url, callback=self.parse_agent, 
        meta={'item': item, 'agent_urls' agent_urls}) 
1

Importanforderungen von scrapy erstellen Sie eine Hash- und eine Agentenliste und hängen Sie diese Liste mit den Daten aus den Anfragen an.

from scrapy import requests 

listing = { "title" : "amazing listing", "agents" : [ ] } 

agentUrls = ["list", "of", "urls", "from", "scraped", "page"] 

for agentUrl in agentUrls: 
    agentPage = requests.get(agentUrl) 
    agentTree = html.fromstring(page.content) 
    name = agentTree.xpath('//node[@id="AgentName"]/text()').extract_first() 
    email = agentTree.xpath('//node[@id="AgentEmail"]/text()').extract_first() 
    agent = { "name" : name, "email": email } 
    listings.agents.append(agent) 
Verwandte Themen