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
相关产品推荐
相关产品推荐

