Xpath正确,但在刮取后无结果

时间:2019-06-27 02:56:40

标签: xpath web-scraping scrapy

我正在尝试抓取以下网站的所有城市名称: https://www.zomato.com/directory

我尝试使用以下xpath。

python
#1st approach:
def parse(self,response):
    cities_name = response.xpath('//div//h2//a/text()').extract_first()
    items['cities_name'] = cities_name
    yield items 
 #2nd approach:

def parse(self,response):
 for city in response.xpath("//div[@class='col-l-5 col-s-8 item pt0 pb5 
   ml0']"):
        l = ItemLoader(item = CountryItem(),selector = city)
        l.add_xpath("cities_name",".//h2//a/text()")
        yield l.load_item()
        yield city

实际结果:抓取0页并抓取0个项目
预期:阿德莱德,巴拉瑞特等

3 个答案:

答案 0 :(得分:1)

首先要注意的是:
您的xpath太具体了。 html中的CSS类并不总是具有可靠的顺序。 class1 class2最终可能是class2 class1,甚至涉及到一些语法混乱的问题,例如尾随空格:class1 class2

当您将xpath直接匹配到[@class="class1 class2"]时,它很有可能会失败。相反,您应该尝试使用contains函数。

第二:
您的cities_name xpath中有一个小错误。在html正文中,其a> h2>文本,在您的代码中,其为h2>a>text

可以这么说,我设法使其与这些CSS和xpath选择器一起使用:

$ parsel "https://www.zomato.com/directory"                                                                           
> p.mb10>a>h2::text +first                                                                                            
Adelaide
> p.mb10>a>h2::text +len                                                                                              
736
> -xpath                                                                                                              
switched to xpath
> //p[contains(@class,"mb10")]/a/h2/text() +first                                                                     
Adelaide
> //p[contains(@class,"mb10")]/a/h2/text() +len                                                                       
736

parselcli-https://github.com/Granitosaurus/parsel-cli

答案 1 :(得分:0)

您的XPath错误:

def parse(self,response):
 for city_node in response.xpath("//h2"):
        l = ItemLoader(item = CountryItem(), selector = city_node)
        l.add_xpath("city_name", ".//a/text()")
        yield l.load_item()

答案 2 :(得分:0)

您无法从该页面获得任何结果的主要原因是因为该站点的html元素格式不正确。您可以使用html5lib解析器获得结果。我尝试过使用不同的解析器,但是我刚才提到的解析器可以解决问题。以下是您如何做到的。不过,我使用了CSS选择器。

import scrapy
from bs4 import BeautifulSoup

class ZomatoSpider(scrapy.Spider):
    name = "zomato"

    start_urls= ['https://www.zomato.com/directory']

    def parse(self, response):
        soup = BeautifulSoup(response.text, 'html5lib')
        for item in soup.select(".row h2 > a"):
            yield {"name":item.text}