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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 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
目录
相关文章
|
18天前
|
数据采集 存储 JavaScript
如何使用Cheerio与jsdom解析复杂的HTML结构进行数据提取
在现代网页开发中,复杂的HTML结构给爬虫技术带来挑战。传统的解析库难以应对,而Cheerio和jsdom在Node.js环境下提供了强大工具。本文探讨如何在复杂HTML结构中精确提取数据,结合代理IP、cookie、user-agent设置及多线程技术,提升数据采集的效率和准确性。通过具体示例代码,展示如何使用Cheerio和jsdom解析HTML,并进行数据归类和统计。这种方法适用于处理大量分类数据的爬虫任务,帮助开发者轻松实现高效的数据提取。
如何使用Cheerio与jsdom解析复杂的HTML结构进行数据提取
|
4天前
|
存储 关系型数据库 MySQL
技术解析:MySQL中取最新一条重复数据的方法
以上提供的两种方法都可以有效地从MySQL数据库中提取每个类别最新的重复数据。选择哪种方法取决于具体的使用场景和MySQL版本。子查询加分组的方法兼容性更好,适用于所有版本的MySQL;而窗口函数方法代码更简洁,执行效率可能更高,但需要MySQL 8.0及以上版本。在实际应用中,应根据数据量大小、查询性能需求以及MySQL版本等因素综合考虑,选择最合适的实现方案。
26 6
|
14天前
|
前端开发 JavaScript C#
移动应用开发中的跨平台框架解析
【9月更文挑战第5天】在移动应用开发领域,跨平台框架因其“一次编写,处处运行”的便利性而受到开发者的青睐。本文将深入探讨几种流行的跨平台框架,包括React Native、Flutter和Xamarin,并比较它们的优势与局限。我们将通过代码示例揭示这些框架如何简化移动应用的开发过程,同时保持高性能和良好的用户体验。无论你是新手还是有经验的开发者,这篇文章都将成为你了解和选择跨平台框架的宝贵资源。
46 19
|
18天前
|
XML JSON API
淘宝京东商品详情数据解析,API接口系列
淘宝商品详情数据包括多个方面,如商品标题、价格、图片、描述、属性、SKU(库存量单位)库存、视频等。这些数据对于买家了解商品详情以及卖家管理商品都至关重要。
|
12天前
|
存储 JSON API
Python编程:解析HTTP请求返回的JSON数据
使用Python处理HTTP请求和解析JSON数据既直接又高效。`requests`库的简洁性和强大功能使得发送请求、接收和解析响应变得异常简单。以上步骤和示例提供了一个基础的框架,可以根据你的具体需求进行调整和扩展。通过合适的异常处理,你的代码将更加健壮和可靠,为用户提供更加流畅的体验。
39 0
|
20天前
|
监控 安全 网络安全
|
20天前
|
C# Windows 开发者
超越选择焦虑:深入解析WinForms、WPF与UWP——谁才是打造顶级.NET桌面应用的终极利器?从开发效率到视觉享受,全面解读三大框架优劣,助你精准匹配项目需求,构建完美桌面应用生态系统
【8月更文挑战第31天】.NET框架为开发者提供了多种桌面应用开发选项,包括WinForms、WPF和UWP。WinForms简单易用,适合快速开发基本应用;WPF提供强大的UI设计工具和丰富的视觉体验,支持XAML,易于实现复杂布局;UWP专为Windows 10设计,支持多设备,充分利用现代硬件特性。本文通过示例代码详细介绍这三种框架的特点,帮助读者根据项目需求做出明智选择。以下是各框架的简单示例代码,便于理解其基本用法。
59 0
|
20天前
|
数据库 Java 监控
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
36 0
|
20天前
|
开发者 Java
JSF EL 表达式:乘技术潮流之风,筑简洁开发之梦,触动开发者心弦的强大语言
【8月更文挑战第31天】JavaServer Faces (JSF) 的表达式语言 (EL) 是一种强大的工具,允许开发者在 JSF 页面和后台 bean 间进行简洁高效的数据绑定。本文介绍了 JSF EL 的基本概念及使用技巧,包括访问 bean 属性和方法、数据绑定、内置对象使用、条件判断和循环等,并分享了最佳实践建议,帮助提升开发效率和代码质量。
26 0
|
20天前
|
Web App开发 IDE 测试技术
自动化测试的利器:Selenium 框架深度解析
【8月更文挑战第31天】在软件开发的世界中,自动化测试是提高产品质量和开发效率不可或缺的一环。本文将深入探讨Selenium这一强大的自动化测试工具,从其架构、优势到实战应用,一步步揭示如何利用Selenium框架提升软件测试的效率和准确性。通过具体的代码示例,我们将展示Selenium如何简化测试流程,帮助开发者快速定位问题,确保软件的稳定性和可靠性。无论你是测试新手还是资深开发者,这篇文章都将为你打开一扇通往高效自动化测试的大门。

推荐镜像

更多