2016-09-27 70 views
2

我是使用Scrapy的新手,并尝试使用Xpath获取页面上所有列表的URL。在Scrapy中使用XPath

第一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()