中间件——爬取网易新闻内容

这篇具有很好参考价值的文章主要介绍了中间件——爬取网易新闻内容。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

中间件:

  • 下载中间件
    • 位置:引擎和下载器之间
    • 作用:批量拦截到整个工程中所有的请求和响应
    • 拦截请求:
      • UA伪装:process_request
      • 代理IP:process_exception:return request
    • 拦截响应:
      • 篡改响应数据,响应对象
      • 需求:爬取网易新闻中的新闻数据(标题和内容)
        • 1.通过网易新闻的首页解析出五大板块对应的详情页的url(没有动态加载)
        • 2.每一个板块对应的新闻标题都是动态加载出来的(动态加载)
        • 3.通过解析出每一条新闻详情页的url获取详情页的页面源码,解析出新闻内容

需求分析

由于要解析不同新闻板块、每个新闻的标题和新闻详情信息,而这些又不是在一个url,所以需要使用三个parse函数进行解析。
由于每一个新闻板块的ur里面的新闻标题都是动态加载出来的,所以需要使用selenium才能得到动态加载出的数据。
那么如何在scrapy中使用selenium呢?
具体的实现方法就是:使用中间件对发起请求的响应数据进行拦截,并将响应数据修改为已动态加载数据的response响应。 如果我发起的url是我需要发起的url,那就对响应数据进行拦截,然后将用selenium得到的响应数据进行作为response返回,达到以假乱真的效果。

如何在scrapy中使用selenium?

在爬虫文件wangyi.py中,在类中初始化时,初始化一个浏览器对象,这样可以保证这个浏览器对象只产生了一次。
同时也要重写父类的关闭操作,将浏览器关闭。

class WangyiSpider(scrapy.Spider):
    name = "wangyi"
    # allowed_domains = ["www.xxx.com"]
    start_urls = ["https://news.163.com/"]
    model_url_list = []     # 得到国内、国际、军事、航空四大模块的url

    def __init__(self):
        # 实例化一个浏览器对象
        options = webdriver.ChromeOptions()
        options.add_experimental_option("excludeSwitches", ["enable-logging"])
        serivce = Service(executable_path='E:\\python\爬虫\\7章:动态加载数据处理\\chromedriver.exe')
        self.browser = webdriver.Chrome(service=serivce, options=options)

	# 重写父类的关闭操作
	def closed(self, spider):
    self.browser.quit()

解析新闻板块url、新闻标题、新闻详情页url

    def parse(self, response):
        li_list = response.xpath('//*[@id="index2016_wrap"]/div[3]/div[2]/div[2]/div[2]/div/ul/li')     # 得到所有的li标签
        # print("li_list:\n", li_list)
        my_list = [1, 2]     # 下标是从0开始的,只解析国内国际的
        for i in my_list:
            model_url = li_list[i].xpath('./a/@href').extract_first()
            self.model_url_list.append(model_url)
        # print(self.model_url_list)
        for url in self.model_url_list:
            yield scrapy.Request(url=url, callback=self.parse_model)

    def parse_model(self, response):
        # 解析每个模块下的新闻标题
        div_list = response.xpath("/html/body/div/div[3]/div[3]/div[1]/div[1]/div/ul/li/div/div")
        for div in div_list:
            title = div.xpath('.//h3/a/text()').extract_first()
            detail_url = div.xpath('.//h3/a/@href').extract_first()

            item = WangyiproItem()
            item['title'] = title
            yield scrapy.Request(url=detail_url, callback=self.parse_detail, meta={'item':item})

    def parse_detail(self, response):
        # 解析每个新闻详情页下的文字
        content = response.xpath('//*[@id="content"]/div[2]//text()').extract()
        content = ''.join(content)
        item = response.meta['item']
        item['content'] = content
        yield item

处理下载中间件,修改响应数据。

这里修改响应数据是在process_response()函数中实现的。
那么我如何判断我当前发起的url是否是我需要发起selenium动态加载数据的url呢?
上面提到的类WangyiSpider 其实是一个spider类的子类。同时也对应def process_response(self, request, response, spider): 中的spider。所以将需要发起请求的url放到spider类中作为一个类变量,然后通过spider.model_url_list 就可以得到所有我需要发起selenium动态加载数据的url。

class WangyiSpider(scrapy.Spider):
    name = "wangyi"
    # allowed_domains = ["www.xxx.com"]
    start_urls = ["https://news.163.com/"]
    model_url_list = []     # 得到国内、国际 二大模块的url


# middlewares.py
class WangyiproDownloaderMiddleware:
	# .....
	    def process_response(self, request, response, spider):
        # Called with the response returned from the downloader.
        # 将爬虫中的实例化浏览器对象取出
        browser = spider.browser
        if request.url in spider.model_url_list:	# 如果发起的请求是在spider.model_url_list中,就使用selenium请求动态数据。
            browser.get(request.url)
            sleep(3)
            page_text = browser.page_source     # 包含了动态加载数据的页面
            # 实例化新的响应对象(此响应对象拥有selenium的动态加载的数据),然后返回这个新的响应对象
            new_response = HtmlResponse(url=response.url, body=page_text  encoding='utf-8', request=request)
            return new_response
        else:
            return response

别忘记在settings.py中开启下载中间件文章来源地址https://www.toymoban.com/news/detail-728513.html

DOWNLOADER_MIDDLEWARES = {
   "wangyiPro.middlewares.WangyiproDownloaderMiddleware": 543,
}

到了这里,关于中间件——爬取网易新闻内容的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • hyperf 学习 三、中间件

    文档地址:Hyperf 中间件的原理就是请求时拦截并进行处理,再传到对应的回调,处理返回数据。 流程:request- middleware-response。 中间件在路由定义时配置。所以根据上一篇文章hyperf 学习 二、路由_lsswear的博客-CSDN博客 中注释路由 Controller、AutoController可以配置 options。 后来查

    2024年02月12日
    浏览(46)
  • NestJS 的 中间件 学习

    中间件是在路由处理程序之前调用的函数。中间件函数可以访问 请求 和 响应 对象。在程序中我们可以让多个中间件串起来一起使用,当多个中间件一起使用时我们可以使用 next() 调用下一个中间件。 中间件主要是可以实现如下功能: 执行任何代码 更改请求和响应对象 结束

    2024年02月15日
    浏览(38)
  • 消息中间件Kafuka学习——初次配置使用

    MQ本质 : 例如 ActiveMQ、RabbitMQ、RocketMQ 等中间件。采用这种模型,本质就是将要推送的数据,不在存放在当前应用程序的内存中,而是将数据存放到另一个专门负责数据处理的应用程序中,从而实现服务解耦。 kafuka模型 : 如果你看不懂这些概念没关系,我会带着大家一起梳理

    2023年04月10日
    浏览(36)
  • Python学习(3)- 消息中间件rabbitmq

    消息队列中间件是分布式系统中重要的组件,主要解决 应用解耦 , 异步消息 , 流量削锋 等问题,实现高性能,高可用,可伸缩和最终一致性架构 rabbitmq 简单模式 生产者: 链接rabbitmq 创建队列 向指定的队列中插入数据 交换机模式 发布订阅模式 模式 模糊匹配模式

    2024年02月22日
    浏览(51)
  • 六、用 ChatGPT 学习 Eureka 中间件源码

    目录 一、实验介绍 二、背景 三、ChatGPT 帮助分析 Eureka 源码 3.1 Eureka 源码在哪

    2024年02月16日
    浏览(46)
  • express学习笔记5 - 自定义路由异常处理中间件

    修改router/index.js,添加异常处理中间件 完整代码 创建 utils/constant:(为了方便后期统一维护,单独拉出来定义) 然后刷新http://localhost:8000/user  这就完成了

    2024年02月14日
    浏览(48)
  • Nginx 学习(十)高可用中间件的配置与实现

    调度器出现单点故障,如何解决? Keepalived实现了高可用集群 Keepalived最初是为LVS设计的,专门监控各服务器节点的状态 Keepalived后来加入了VRRP功能,防止单点故障 Keepalived检测每个服务器节点状态,当服务器节点异常或工作出现故障, Keepalived将故障节点从集群系统中剔除,故

    2024年02月09日
    浏览(110)
  • Go学习第十七章——Gin中间件与路由

    Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等 即比如,如果访问一个网页的话,不管访问什么路径都需要进行登录,

    2024年02月07日
    浏览(47)
  • RabbitMQ-消息中间件学习记录(what-how-why)

    什么是消息中间件 简单的来说就是消息队列中间件,生产者发送消息到中间件,消息中间件用于 保存消息并发送消息到消费者。 消息中间件RabbitMQ的基本组件 1)producer -生产者 2)customer -消费者 3)broker (经纪人)- MQ服务器,管理消息对列、消息及相关消息。(接收并存储生

    2024年02月13日
    浏览(47)
  • 《分布式中间件技术实战:Java版》学习笔记(一):抢红包

    数据库建表 (1)red_send_record 记录用户发送了若干总金额的若干个红包。 (2)red_detail 记录用户发送的红包被分成的小红包金额。 (3)red_rob_record 记录用户抢到的红包金额。 随机生成红包金额 红包金额的最小单位是分,将红包金额放大100倍到int类型(为了方便生成随机数),保证

    2024年02月10日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包