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中间件的使用的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!

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

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

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

相关推荐
思则变2 小时前
[Pytest] [Part 2]增加 log功能
开发语言·python·pytest
漫谈网络3 小时前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
try2find4 小时前
安装llama-cpp-python踩坑记
开发语言·python·llama
博观而约取5 小时前
Django ORM 1. 创建模型(Model)
数据库·python·django
精灵vector7 小时前
构建专家级SQL Agent交互
python·aigc·ai编程
Zonda要好好学习7 小时前
Python入门Day2
开发语言·python
Vertira7 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
太凉7 小时前
Python之 sorted() 函数的基本语法
python
项目題供诗7 小时前
黑马python(二十四)
开发语言·python
晓13138 小时前
OpenCV篇——项目(二)OCR文档扫描
人工智能·python·opencv·pycharm·ocr