Scrapy爬取Booking.com酒店坐标返回None值,求错误排查
Scrapy爬虫提取Booking.com坐标返回None的问题排查
问题描述
我尝试从Booking.com的目标页面提取id为hotel_address元素的坐标信息,但编写的Scrapy爬虫代码返回None值,请问错误出在哪里?
我编写的爬虫代码
class CrawlerSpider(scrapy.Spider): name='crawler' headers={'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36'} start_urls=['https://www.booking.com/hotel/it/heart-of-san-lorenzo-roma12345678910111213141516171819202122.it.html?group_adults=1;no_rooms=1;'] # def start_requests(self): for link in self.start_urls: yield scrapy.Request(url=link,headers=self.headers, callback=self.parse) def parse(self, response): coordinate="" print('===========================================================') coordinate=response.xpath('//*[@id="hotel_address"]/@data-atlas-latlng/text()').get() print(coordinate) print('===========================================================') process=CrawlerProcess() process.crawl(CrawlerSpider) process.start()
错误原因与解决方法
1. XPath语法错误(核心问题)
你的XPath表达式//*[@id="hotel_address"]/@data-atlas-latlng/text()存在错误:@data-atlas-latlng已经是属性节点,直接获取其值即可,不需要追加/text()——属性节点本身没有子文本节点,这会导致XPath匹配不到任何内容,返回None。
修正后的XPath应为:
//*[@id="hotel_address"]/@data-atlas-latlng
2. 潜在的动态渲染问题
Booking.com部分页面内容可能通过JavaScript动态生成,如果修正XPath后仍返回None,需确认目标元素是否存在于静态HTML中:
- 使用
scrapy shell测试:运行scrapy shell "目标URL",在交互环境中执行response.xpath('//*[@id="hotel_address"]/@data-atlas-latlng').get()查看结果。 - 若返回None,说明内容是动态加载的,需要使用
scrapy-splash或Playwright等工具处理JavaScript渲染的页面。
3. 请求头完整性不足
虽然你设置了User-Agent,但部分网站会校验更多请求头字段(如Accept、Referer),建议补充完整请求头以模拟真实浏览器请求,避免被识别为爬虫。
修正后的代码示例
import scrapy from scrapy.crawler import CrawlerProcess class CrawlerSpider(scrapy.Spider): name='crawler' headers={ 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' } start_urls=['https://www.booking.com/hotel/it/heart-of-san-lorenzo-roma12345678910111213141516171819202122.it.html?group_adults=1;no_rooms=1;'] def start_requests(self): for link in self.start_urls: yield scrapy.Request(url=link, headers=self.headers, callback=self.parse) def parse(self, response): print('===========================================================') # 修正XPath,移除多余的/text() coordinate = response.xpath('//*[@id="hotel_address"]/@data-atlas-latlng').get() print(coordinate) print('===========================================================') process = CrawlerProcess() process.crawl(CrawlerSpider) process.start()
内容的提问来源于stack exchange,提问作者Mojsa
相关产品推荐
相关产品推荐

