Scrapy中间件的使用

使用 Scrapy 中间件爬取网易新闻四大板块数据

在爬取动态加载网页数据时,我们经常需要结合 Scrapy 的强大爬虫框架和自动化工具的功能,来获取完整的页面数据。本文将以 网易新闻四大板块(国内、国际、军事、航空)数据爬取 为例,讲解如何使用 Scrapy 中间件 实现数据抓取。


1. Scrapy 中间件概述

Scrapy 提供了两种中间件:

  • 下载中间件:位于引擎和下载器之间,用于拦截和修改请求及响应。常见用途包括添加请求头、设置代理、修改响应内容等。
  • 爬虫中间件:位于引擎和爬虫之间,主要用于对传递到爬虫的数据进行处理,一般很少使用。

在本次项目中,我们将重点使用 下载中间件,并结合自动化工具处理动态加载页面的问题。


2. 项目目标

网易新闻的四大板块页面结构一致,我们希望爬取以下数据:

  1. 国内新闻
  2. 国际新闻
  3. 军事新闻
  4. 航空新闻

这些板块每次访问只能获取前 50 条数据,部分板块需要通过滚动加载或点击"加载更多"按钮来获取全部内容。


3. 项目实现

3.1 环境准备

安装 Scrapy 和 Selenium(自动化工具):

bash 复制代码
pip install scrapy selenium

确保已安装浏览器驱动,例如 ChromeDriver,并将其路径添加到环境变量。

3.2 创建 Scrapy 项目

使用以下命令初始化 Scrapy 项目:

bash 复制代码
scrapy startproject wy_news

创建爬虫文件:

bash 复制代码
cd wy_news
scrapy genspider wyxw news.163.com
3.3 爬虫代码实现

(1)爬取四个板块的 URL

以下代码解析网易新闻主页,提取四个板块的 URL:

python 复制代码
import scrapy

class WyxwSpider(scrapy.Spider):
    name = "wyxw"
    start_urls = ["https://news.163.com/"]  # 网易新闻主页
    urls = []  # 存储四个板块的 URL

    def parse(self, response):
        # 解析主页,获取四个板块的 URL
        lis = response.xpath('//div[@class="ns_area list"]/ul/li')
        lis2 = lis[1:3] + lis[4:6]  # 选取国内、国际、军事、航空板块
        for li in lis2:
            news_url = li.xpath('./a/@href').get()
            self.urls.append(news_url)
            # 发起请求获取板块数据
            yield scrapy.Request(url=news_url, callback=self.parse_news)

(2)解析新闻标题

对每个板块的 URL 发送请求,提取新闻标题:

python 复制代码
    def parse_news(self, response):
        # 解析板块页面中的新闻标题
        divs = response.xpath('//div[@class="hidden"]/div')
        for div in divs:
            title = div.xpath('./a/text()').get()
            print(title)

3.4 处理滚动加载

对于需要滚动加载的页面,我们使用 Selenium 模拟滚动和点击操作。通过 Scrapy 的下载中间件结合 Selenium,自动加载全部数据。

中间件代码:

python 复制代码
from scrapy import signals
from scrapy.http import HtmlResponse
from selenium.webdriver import Chrome

class Scrapy4DownloaderMiddleware:

    @classmethod
    def from_crawler(cls, crawler):
        s = cls()
        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
        return s

    def process_response(self, request, response, spider):
        # 判断当前 URL 是否需要使用自动化技术
        if request.url in spider.urls:
            driver = Chrome()
            driver.get(request.url)
            while True:
                # 模拟滚动
                driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                try:
                    load_more_btn = driver.find_element_by_css_selector('.load_more_btn')
                    load_more_btn.click()
                except Exception:
                    # 判断是否加载完毕
                    if "display: block;" in driver.find_element_by_css_selector('.load_more_tip').get_attribute('style'):
                        break
            # 获取页面源码并封装为 Scrapy 响应对象
            body = driver.page_source
            driver.quit()
            return HtmlResponse(url=request.url, body=body, encoding='utf-8', request=request)
        else:
            return response

配置中间件:settings.py 文件中启用中间件:

python 复制代码
DOWNLOADER_MIDDLEWARES = {
    'wy_news.middlewares.Scrapy4DownloaderMiddleware': 543,
}

4. 注意事项

  1. 开发环境:确保浏览器和驱动版本匹配。
  2. 响应处理 :将自动化工具的输出封装为 Scrapy 的响应对象(HtmlResponse),以便继续使用 Scrapy 的解析能力。
  3. 调试:对于动态加载页面,先用浏览器开发者工具检查加载逻辑,确认滚动或按钮是否正确模拟。

5. 总结

通过结合 Scrapy 中间件和自动化工具,我们解决了动态加载页面数据的抓取问题。这种方法不仅可以应对网易新闻的场景,还适用于其他需要滚动加载或动态交互的网页。

完整代码和实现步骤提供了一个基础框架,希望大家能灵活应用到自己的项目中!

以上就是Scrapy中间件的使用的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!

如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.

学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.

人生路漫漫, 白鹭常相伴!!!

相关推荐
有味道的男人9 分钟前
电商效率翻倍:京东全量商品信息抓取
python
原来是猿32 分钟前
博客系统自动化测试实战总结
python
小江的记录本1 小时前
【JVM虚拟机】JVM调优:常用JVM参数、调优核心指标、OOM排查、GC日志分析、Arthas工具使用(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·后端·python·spring·面试
大数据魔法师1 小时前
Streamlit(十三)- API 参考文档(六)- 媒体展示组件
python·web
爱写代码的倒霉蛋1 小时前
Hello-Agents的第一个练习-5分钟实现一个智能体(实现详解)
python
金銀銅鐵1 小时前
[Java] 用图形化界面演示 iadd, isub, iconst_<i> 指令的效果
java·后端·python
春日见2 小时前
五分钟入门 强化学习---DQN(Deep Q Net)算法与实现
人工智能·python·深度学习·算法·microsoft·机器学习
SomeOtherTime2 小时前
Geojson相关(AI回答)
java·前端·python
weelinking2 小时前
【产品】11_实现后端接口——数据在背后如何流动
java·人工智能·python·sql·oracle·json·ai编程
Dxy12393102162 小时前
三种方式避坑:案例 + 解决方法
python·mysql