Scrapy框架-通过scrapy_splash解析动态渲染的数据

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 前言对于那些通过JS来渲染数据的网站,我们要解析出它的html来才能取到想要的数据,通常有两种解决办法:1、通过selenim调用浏览器(如chrome firefox等)来爬取,将解析的任务交给浏览器。

前言

对于那些通过JS来渲染数据的网站,我们要解析出它的html来才能取到想要的数据,通常有两种解决办法:
1、通过selenim调用浏览器(如chrome firefox等)来爬取,将解析的任务交给浏览器。
2、通过splash来解析数据,scrapy可以直接从splash的【空间】中拿到渲染后的数据。

这里介绍scrapy_splash

有个坑

根据它的文档,我们可以知道它依赖于Docker服务,所以你想要使用scrapy_splash就需要先安装docker并跑起来。再根据它的文档进行安装、启动等操作(其实这里有个坑):

$ docker run -p 8050:8050 scrapinghub/splash

项目启动的时候,如果通过这个命令启动,他其实默认给你启动的是http://127.0.0.1:8050/,你可以用浏览器打开来看,看到这个页面就算正常启动了


splash正常启动页面-通过浏览器访问

所以,它的官方示例代码下一句代码(在settings.py中配置):

 SPLASH_URL = 'http://192.168.59.103:8050'

你在使用的时候如果按照这句来写,是无法连接splash的,必须写成:

"SPLASH_URL": 'http://127.0.0.1:8050'

其他的配置可以按照文档来写。

代码中的使用

如果使用动态settings配置(避免影响其他爬虫)的话,可以在具体的spider文件中新增:

custom_settings = {
    """ 动态settings配置 """
    "SPLASH_URL": 'http://127.0.0.1:8050',
    "DOWNLOADER_MIDDLEWARES": {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
    },
    "SPIDER_MIDDLEWARES": {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
    },
    "DUPEFILTER_CLASS": 'scrapy_splash.SplashAwareDupeFilter',
    "HTTPCACHE_STORAGE": 'scrapy_splash.SplashAwareFSCacheStorage',
}
name = 'tsinghua'
allowed_domains = ['tv.tsinghua.edu.cn']
start_urls = ['http://tv.tsinghua.edu.cn/publish/video/index.html']

然后再使用的时候,需要将哪个动态页面解析,就要用SplashRequest来发起请求,而不是之前的scrapy.Request来发起,其他的如callback、meta、url都是一样的(如果不一样请以文档为准)下面我放出清华大学视频站的解析代码:

def parse(self, response):
    """
    获取导航链接, 自动爬取所有导航url, 交给parseList方法
    为了获取js渲染的翻页, 这里用scrapy-splash的SplashRequest来构造请求, 以获得js渲染后的的html数据
     """
    totalNav = response.css('#nav li')
    for i in totalNav:
        urls = i.css('a::attr("href")').extract_first()
        yield SplashRequest(url=parse.urljoin(response.url, urls), args={"wait": 1}, callback=self.parseList)

def parseList(self, response):
    """ 在列表页获取详情页的url以及视频封面, 传递给parseDetails方法, 最终获取视频和封面等信息 """
    totalUrl = response.css('.picnewslist2.clearfix .clearfix ')
    for i in totalUrl:
        urls = parse.urljoin(response.url, i.css('.contentwraper figcaption a::attr("href")').extract_first())
        imagesUrl = parse.urljoin(response.url, i.css('.picwraper img::attr("src")').extract_first())
        yield Request(url=urls, meta={"imagesUrl": imagesUrl}, callback=self.parseDetails)

    """ 
    翻页操作 
        借助scrapy-splash来解析js渲染的html
        取出"上一页, 下一页"的页码, 通过re正则来匹配其中的数值
        对url进行判断, 是否是第一页。根据url构造不同的下一页nexPageUrl
        最后借助scrapy-splash继续解析下一页的html
    """
    nextPageList = response.css('a.p::attr("onclick")').extract()
    if len(nextPageList) >= 2:
        matchRule = re.search('\d+', nextPageList[1])
        if matchRule:
            nextPageNumber = matchRule.group(0)
            thisPageRule = re.search('index_\d+', response.url)
            if thisPageRule:
                thisPageNumber = thisPageRule.group(0).replace('index_', '')
                nexPageUrl = response.url.replace(thisPageNumber, nextPageNumber)
                yield SplashRequest(url=nexPageUrl, callback=self.parseList)
            else:
                nexPageUrlJoin = 'index_' + nextPageNumber
                nexPageUrl = response.url.replace('index', nexPageUrlJoin)
                yield SplashRequest(url=nexPageUrl, callback=self.parseList)

def parseDetails(self, response):
    """ 抽取视频详情, 交给对应item进行序列化 """
    imagesUrl =response.meta['imagesUrl']
    loaders = tsinghuaVedioItemLoader(item=tsinghuaVedioItem(), response=response)
    loaders.add_css("title", "article.article h1::text")  # 标题
    loaders.add_css("articleContent", '#play_mobile source::attr("src")')  # 内容
    loaders.add_value("imagesUrl", imagesUrl)  # 视频封面地址
    loaders.add_value("articleType", 2)  # 类型:视频
    loaders.add_value("addtime", datetime.now())
    loaders.add_value("schoolName", "清华大学")
    loaders.add_value("schoolID", 6)
    items = loaders.load_item()
    yield items
目录
相关文章
|
1月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
55 8
|
4天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
1月前
|
数据采集 自然语言处理 搜索推荐
基于qwen2.5的长文本解析、数据预测与趋势分析、代码生成能力赋能esg报告分析
Qwen2.5是一款强大的生成式预训练语言模型,擅长自然语言理解和生成,支持长文本解析、数据预测、代码生成等复杂任务。Qwen-Long作为其变体,专为长上下文场景优化,适用于大型文档处理、知识图谱构建等。Qwen2.5在ESG报告解析、多Agent协作、数学模型生成等方面表现出色,提供灵活且高效的解决方案。
168 49
|
26天前
|
XML JSON JavaScript
HttpGet 请求的响应处理:获取和解析数据
HttpGet 请求的响应处理:获取和解析数据
|
1月前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
1月前
|
数据采集 存储 自然语言处理
基于Qwen2.5的大规模ESG数据解析与趋势分析多Agent系统设计
2022年中国上市企业ESG报告数据集,涵盖制造、能源、金融、科技等行业,通过Qwen2.5大模型实现报告自动收集、解析、清洗及可视化生成,支持单/多Agent场景,大幅提升ESG数据分析效率与自动化水平。
117 0
|
1月前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
34 0
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
4天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
4天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

推荐镜像

更多