2016-09-27 10 views
2

Я новичок в использовании Scrapy и пытаюсь получить все URL-адреса списков на странице с помощью Xpath.Использование XPath с Scrapy

Первый работает

XPath
sel.xpath('//[contains(@class, "attraction_element")]') 

но второй XPath дает ошибку

get_parsed_string(snode_attraction, '//[@class="property_title"]/a/@href') 

Что не так и как мы можем это исправить?

Scrapy Код

def clean_parsed_string(string): 
    if len(string) > 0: 
     ascii_string = string 
     if is_ascii(ascii_string) == False: 
      ascii_string = unicodedata.normalize('NFKD', ascii_string).encode('ascii', 'ignore') 
     return str(ascii_string) 
    else: 
     return None 


def get_parsed_string(selector, xpath): 
    return_string = '' 
    extracted_list = selector.xpath(xpath).extract() 
    if len(extracted_list) > 0: 
     raw_string = extracted_list[0].strip() 
     if raw_string is not None: 
      return_string = htmlparser.unescape(raw_string) 
    return return_string 


class TripAdvisorSpider(Spider): 
    name = 'tripadvisor' 

    allowed_domains = ["tripadvisor.com"] 
    base_uri = "http://www.tripadvisor.com" 
    start_urls = [ 
     base_uri + '/Attractions-g155032-Activities-c47-t163-Montreal_Quebec.html' 
    ] 


    # Entry point for BaseSpider 
    def parse(self, response): 

     tripadvisor_items = [] 

     sel = Selector(response) 
     snode_attractions = sel.xpath('//[contains(@class, "attraction_element")]') 

     # Build item index 
     for snode_attraction in snode_attractions: 
      print clean_parsed_string(get_parsed_string(snode_attraction, '//[@class="property_title"]/a/@href')) 

ответ

3

Оба не являются допустимыми выражениями XPath, вам нужно добавить имена тегов после //. Вы можете также использовать подстановочные *:

snode_attractions = sel.xpath('//*[contains(@class, "attraction_element")]') 

Обратите внимание, что в стороне от вас второго выражения XPath, которое используется в цикле должно быть зависят от конкретных условий и начинаются с точкой:

# Build item index 
for snode_attraction in snode_attractions: 
    print clean_parsed_string(get_parsed_string(snode_attraction, './/*[@class="property_title"]/a/@href')) 

Также обратите внимание что вам не нужно создавать объект Selector и использовать непосредственно ссылку response.xpath().


Обратите внимание, что более кратким и, возможно, более читаемым версии одной и той же логической реализации будет использовать CSS селекторы:

snode_attractions = response.css('.attraction_element') 
for snode_attraction in snode_attractions: 
    print snode_attraction.css('.property_title > a::attr("href")').extract_first()