You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy新手求助:联合国网站爬取无数据,疑网页渲染异常

解决Scrapy + Splash爬取联合国OHCHR网站无数据的问题

我明白你作为Scrapy新手遇到这种动态渲染问题有多头疼——带表单和JS的官方站点,往往在反爬、动态加载逻辑上都比较严谨,很容易踩坑。结合你的描述和代码片段,我整理了几个大概率能解决问题的方向:

1. 补全Splash核心配置

你已经设置了SPLASH_URL,但Splash正常工作还依赖几个关键中间件,先检查你的custom_settings是否补全了这些内容:

custom_settings = {
    'SPLASH_URL': 'http://localhost:8050',
    # 下载中间件:处理Splash的Cookie、渲染逻辑
    'DOWNLOADER_MIDDLEWARES': {
        'scrapy_splash.SplashCookiesMiddleware': 723,
        'scrapy_splash.SplashMiddleware': 725,
        'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
    },
    # 爬虫中间件:去重逻辑适配Splash
    'SPIDER_MIDDLEWARES': {
        'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
    },
    # 替换默认去重器,支持Splash请求
    'DUPEFILTER_CLASS': 'scrapy_splash.SplashAwareDupeFilter',
}

缺了这些配置,Splash的渲染请求根本不会生效,自然拿不到动态加载的数据。

2. 让SplashRequest模拟真实浏览器行为

很多官方站点会检测请求头和加载行为,你需要给请求加上完整的浏览器UA,并且指定等待JS渲染的时间:

def start_requests(self):
    target_url = "你的联合国新闻页面URL"
    yield SplashRequest(
        target_url,
        callback=self.parse,
        args={
            'wait': 3,  # 等待3秒让JS渲染完成,可根据页面加载速度调整
            'timeout': 15,
            'images': 0,  # 禁用图片加载,提升渲染速度
        },
        headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
        }
    )

如果页面需要通过表单筛选新闻(比如选择日期范围、分类),还得用Splash的Lua脚本模拟交互:

# 模拟表单填写+提交的Lua脚本
lua_script = """
function main(splash, args)
    splash:set_user_agent(args.ua)
    assert(splash:go(args.url))
    assert(splash:wait(2))
    -- 填写日期范围(替换成页面实际的表单ID)
    splash:runjs("document.getElementById('startDate').value='2023-01-01'")
    splash:runjs("document.getElementById('endDate').value='2023-12-31'")
    -- 点击提交按钮
    splash:runjs("document.querySelector('.submit-btn').click()")
    assert(splash:wait(3))
    return splash:html()
end
"""

yield SplashRequest(
    target_url,
    callback=self.parse,
    endpoint='execute',  # 指定用执行Lua脚本的端点
    args={
        'lua_source': lua_script,
        'ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
        'url': target_url
    }
)

3. 验证渲染结果是否正确

先别着急写提取逻辑,在parse方法里把Splash返回的内容存成HTML文件,看看是不是真的渲染出了新闻:

def parse(self, response):
    # 保存渲染后的页面,方便排查
    with open('rendered_ohchr.html', 'w', encoding='utf-8') as f:
        f.write(response.text)
    # 临时打印匹配到的新闻数量
    news_nodes = response.css('你的新闻元素选择器')
    print(f"当前页面匹配到{len(news_nodes)}条新闻")
    # 后续提取逻辑...

如果保存的HTML里还是没有新闻,那可能是这几个问题:

  • Splash服务没正常启动:先在浏览器访问http://localhost:8050确认服务是否运行
  • 网站有隐性验证:比如需要特定Cookie,可手动登录后把Cookie加到请求头里
  • 反爬限制:尝试降低爬取频率,或者添加代理IP

4. 检查选择器是否准确

有时候不是渲染的问题,是你用的CSS/XPath选择器不对。打开保存的rendered_ohchr.html,用浏览器开发者工具重新定位新闻元素,确保选择器能精准匹配到内容。

最后提醒下,爬取联合国网站要遵守他们的robots.txt规则,不要高频请求,避免被封禁IP哦。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:29:49