You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Scrapy分页执行但所有页面均返回第一页数据问题排查

问题排查与修复方案

我帮你梳理了代码里的几个核心问题,这应该就是导致所有页面返回第一页数据、数据异常的原因:

1. 重复使用同一个Item对象,导致数据被覆盖

你在parse方法开头就创建了一个HotelAbbasiItem实例,然后在循环里反复给这个实例的字段赋值并yield。因为Python里对象是引用传递的,每次yield的都是同一个Item对象,最后所有输出的Item都会被最后一次循环的赋值覆盖,看起来就像所有数据都是第一页的最后一条。

修复方法:把Item的创建放到for循环内部,每次循环都生成新的实例:

def parse(self,response):
    all_div_parts = response.css('div.hotels-community-tab-common-Card__section--4r93H')
    for part in all_div_parts:
        # 每次循环新建一个Item对象
        items = HotelAbbasiItem()
        reviewer = part.css('a.social-member-event-MemberEventOnObjectBlock__member--35-jC::text').extract()
        DateOfReview = part.css('span::text').extract()
        Nationality = part.css('span.small::text').extract()
        Contribution = part.css('span.social-member-MemberHeaderStats__bold--3z3qh::text').extract()
        ReviewText = part.css('q.location-review-review-list-parts-ExpandableReview__reviewText--gOmRC>span::text').extract()
        Rating = part.css('div.location-review-review-list-parts-RatingLine__bubbles--GcJvM>span::attr(class)').extract()
        
        items['reviewer'] = reviewer
        items['DateOfReview'] = DateOfReview
        items['Nationality'] = Nationality
        items['Contribution'] = Contribution
        items['ReviewText'] = ReviewText
        items['Rating'] = Rating
        
        yield items
    # 翻页逻辑后续修改

2. 翻页选择器错误+反爬机制,导致重复获取第一页

你提到所有页面都返回第一页数据,主要有两个可能:

  • 你当前的翻页选择器div.is-centered>a.primary无法正确定位到TripAdvisor的下一页按钮,导致提取的链接是当前页或者为空,反复请求第一页;
  • TripAdvisor的反爬机制识别了你的爬虫,把所有请求都重定向回第一页。

修复翻页选择器

TripAdvisor的下一页按钮标准选择器是a.nav.next::attr(href),替换原有的翻页逻辑:

# 替换原翻页代码
next_page = response.css('a.nav.next::attr(href)').extract_first()
if next_page:
    next_page_url = response.urljoin(next_page)
    # 添加浏览器请求头,避免被反爬识别
    yield scrapy.Request(
        url=next_page_url,
        callback=self.parse,
        headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
        }
    )

反爬优化建议

TripAdvisor反爬很严格,建议额外做这些设置:

  • settings.py里添加DOWNLOAD_DELAY = 2,控制请求频率,避免被封禁;
  • 长期爬取的话,可以考虑使用代理IP,或者启用Scrapy的Cookies中间件保持会话;
  • 尽量使用extract_first(default='')替代extract()获取单值数据,避免Item里出现空列表,比如:
    reviewer = part.css('a.social-member-event-MemberEventOnObjectBlock__member--35-jC::text').extract_first(default='')
    

内容的提问来源于stack exchange,提问作者Hny

火山引擎 最新活动