Scrapy中间件的使用
使用 Scrapy 中间件爬取网易新闻四大板块数据
在爬取动态加载网页数据时,我们经常需要结合 Scrapy 的强大爬虫框架和自动化工具的功能,来获取完整的页面数据。本文将以 网易新闻四大板块(国内、国际、军事、航空)数据爬取 为例,讲解如何使用 Scrapy 中间件 实现数据抓取。
1. Scrapy 中间件概述
Scrapy 提供了两种中间件:
- 下载中间件:位于引擎和下载器之间,用于拦截和修改请求及响应。常见用途包括添加请求头、设置代理、修改响应内容等。
- 爬虫中间件:位于引擎和爬虫之间,主要用于对传递到爬虫的数据进行处理,一般很少使用。
在本次项目中,我们将重点使用 下载中间件,并结合自动化工具处理动态加载页面的问题。
2. 项目目标
网易新闻的四大板块页面结构一致,我们希望爬取以下数据:
- 国内新闻
- 国际新闻
- 军事新闻
- 航空新闻
这些板块每次访问只能获取前 50 条数据,部分板块需要通过滚动加载或点击“加载更多”按钮来获取全部内容。
3. 项目实现
3.1 环境准备
安装 Scrapy 和 Selenium(自动化工具):
pip install scrapy selenium
确保已安装浏览器驱动,例如 ChromeDriver,并将其路径添加到环境变量。
3.2 创建 Scrapy 项目
使用以下命令初始化 Scrapy 项目:
scrapy startproject wy_news
创建爬虫文件:
cd wy_news
scrapy genspider wyxw news.163.com
3.3 爬虫代码实现
(1)爬取四个板块的 URL
以下代码解析网易新闻主页,提取四个板块的 URL:
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 发送请求,提取新闻标题:
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,自动加载全部数据。
中间件代码:
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
文件中启用中间件:
DOWNLOADER_MIDDLEWARES = {
'wy_news.middlewares.Scrapy4DownloaderMiddleware': 543,
}
4. 注意事项
- 开发环境:确保浏览器和驱动版本匹配。
- 响应处理:将自动化工具的输出封装为 Scrapy 的响应对象(
HtmlResponse
),以便继续使用 Scrapy 的解析能力。 - 调试:对于动态加载页面,先用浏览器开发者工具检查加载逻辑,确认滚动或按钮是否正确模拟。
5. 总结
通过结合 Scrapy 中间件和自动化工具,我们解决了动态加载页面数据的抓取问题。这种方法不仅可以应对网易新闻的场景,还适用于其他需要滚动加载或动态交互的网页。
完整代码和实现步骤提供了一个基础框架,希望大家能灵活应用到自己的项目中!
以上就是Scrapy中间件的使用的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!