我正在尝试抓取以下网站的所有城市名称: 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个项目
预期:阿德莱德,巴拉瑞特等
答案 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
答案 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}