使用Scrapy爬取TripAdvisor评论时,如何选择“所有语言”?
解决TripAdvisor多语言评论评分抓取问题
嘿,作为刚接触Python和Scrapy的新手,碰到这种抓不到非英文评论评分的问题太正常啦!我帮你捋捋怎么搞定~
问题原因
TripAdvisor的评论默认会优先展示英文内容,其他语言的评论通常被放在单独的标签页里,而且很多时候这些内容是动态加载的,或者需要通过URL参数指定语言才能获取到对应的评分数据。你的原始代码只请求了默认的英文页面,自然拿不到其他语言的评分啦。
具体解决方案
我给你两种可行的思路,你可以根据自己的情况选:
思路1:通过URL参数切换语言
打开目标酒店的评论页,手动切换到非英文评论的标签(比如中文、西班牙语),你会发现URL里多了一个filterLang=xx的参数(比如中文是zh,西班牙语是es)。我们只需要在Scrapy请求里带上这个参数,就能直接获取对应语言的评论和评分。
思路2:抓取动态加载的API接口
如果切换标签时页面没有刷新,而是通过AJAX加载内容,那你可以打开浏览器的开发者工具(F12),切换到「Network」标签,找到加载评论的XHR请求。TripAdvisor的评论API通常是类似OverlayWidgetAjax的接口,里面会包含语言、分页等参数,直接请求这个API返回的JSON数据,解析起来会更高效。
修改后的代码示例(思路1)
下面是基于URL参数的代码,支持同时抓取多种语言的评论评分:
import scrapy from scrapy.http import Request import re class ReviewScrapeSpider(scrapy.Spider): name = 'review_scrape' allowed_domains = ['tripadvisor.com'] # 定义你要抓取的语言代码,可根据实际情况添加/修改 target_languages = ['en', 'zh', 'es', 'fr'] # 替换成你实际的酒店基础URL(去掉后面的分页/语言参数) base_hotel_url = 'https://www.tripadvisor.com/Hotel_Review-g60970-d22625...' def start_requests(self): # 为每个语言生成请求 for lang in self.target_languages: # 拼接带语言过滤参数的URL full_url = f"{self.base_hotel_url}&filterLang={lang}" # 把当前语言存入meta,方便后续识别 yield Request(full_url, callback=self.parse_reviews, meta={'current_lang': lang}) def parse_reviews(self, response): current_lang = response.meta['current_lang'] # 提取评论容器 review_containers = response.xpath('//div[contains(@class, "review-container")]') for container in review_containers: # 提取评分:TripAdvisor的评分用class里的数字表示,比如bubble_40对应4分 rating_class = container.xpath('.//span[contains(@class, "ui_bubble_rating")]/@class').get() if rating_class: rating_score = int(re.search(r'bubble_(\d+)', rating_class).group(1)) / 10 yield { 'language': current_lang, 'rating': rating_score, 'review_text': container.xpath('.//p[@class="partial_entry"]/text()').get(default='').strip(), 'review_date': container.xpath('.//span[@class="ratingDate"]/@title').get(default='') } # 处理分页:找到下一页的URL next_page_link = response.xpath('//a[@class="nav next ui_button primary"]/@href').get() if next_page_link: next_page_url = response.urljoin(next_page_link) # 继续传递当前语言参数 yield Request(next_page_url, callback=self.parse_reviews, meta={'current_lang': current_lang})
额外提醒
- 语言代码确认:不同语言的
filterLang参数值可能不同,你可以手动切换标签页看URL里的实际参数(比如中文可能是zh或者zh_CN)。 - 遵守网站规则:不要频繁请求,建议在
settings.py里设置DOWNLOAD_DELAY = 2或者使用代理IP,避免被网站封禁。 - 动态加载处理:如果遇到滚动加载更多评论的情况,你可以考虑使用
scrapy_splash渲染JavaScript,或者直接找到对应的API接口请求JSON数据。
内容的提问来源于stack exchange,提问作者Sayf
相关产品推荐
相关产品推荐

