《Python实战进阶》No20: 网络爬虫开发:Scrapy框架详解

No20: 网络爬虫开发:Scrapy框架详解

摘要

本文深入解析Scrapy核心架构,通过中间件链式处理布隆过滤器增量爬取Splash动态渲染分布式指纹策略四大核心技术,结合政府数据爬取与动态API逆向工程实战案例,构建企业级爬虫系统。提供完整代码与运行结果,包含法律合规设计与反爬对抗方案。


Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。

在这里插入图片描述

运行环境与依赖说明

# 环境要求
Python 3.8+
Redis 6.0+ (分布式场景)# 依赖安装
pip install scrapy==2.8.0 scrapy-splash==0.9.0 scrapy-redis==0.7.2
pip install redis==4.5.5 requests==2.31.0 beautifulsoup4==4.12.2

核心概念与实战代码

1. 中间件链式处理机制

核心逻辑:通过process_requestprocess_response实现请求/响应预处理

# 中间件实现示例:随机User-Agent
class RandomUserAgentMiddleware:def __init__(self):self.user_agents = ["Mozilla/5.0 (Windows NT 10.0...)","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15...)"]def process_request(self, request, spider):request.headers['User-Agent'] = random.choice(self.user_agents)spider.logger.info(f"Using User-Agent: {request.headers['User-Agent']}")# settings.py配置
DOWNLOADER_MIDDLEWARES = {'myproject.middlewares.RandomUserAgentMiddleware': 543,
}

输出日志

[scrapy.core.engine] INFO: Using User-Agent: Mozilla/5.0 (Windows NT 10.0...

2. 增量爬取与布隆过滤器

实现方案:基于Scrapy-Redis的BloomFilter去重

# 布隆过滤器配置(settings.py)
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.BloomFilter"
REDIS_URL = 'redis://localhost:6379'# 启动爬虫(保留历史指纹)
scrapy crawl gov_spider -s SCHEDULER_PERSIST=True

运行效果

[scrapy_redis.scheduler] INFO: Resuming crawl (5678 requests scheduled)

3. Splash渲染与自动代理池

动态页面处理:集成Splash渲染JavaScript

# 使用SplashRequest爬取动态页面
import scrapy
from scrapy_splash import SplashRequestclass DynamicSpider(scrapy.Spider):name = 'dynamic_spider'def start_requests(self):yield SplashRequest(url="https://example.com/ajax-page",callback=self.parse,args={'wait': 2})def parse(self, response):yield {'content': response.xpath('//div[@class="dynamic-content"]/text()').get()}

输出结果

{'content': '这是动态加载的内容'}

4. 分布式爬虫指纹策略

分布式架构:通过Redis共享指纹和队列

# 分布式配置(settings.py)
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'
REDIS_HOST = '192.168.1.100'

运行命令

# 在多台机器上启动
scrapy runspider myspider.py -a slave_id=1
scrapy runspider myspider.py -a slave_id=2

在这里插入图片描述

实战案例

案例1:政府公开数据结构化爬取

目标:爬取国家统计局季度GDP数据

# items.py定义结构
class GovDataItem(scrapy.Item):quarter = scrapy.Field()gdp = scrapy.Field()growth_rate = scrapy.Field()# spiders/gov_spider.py
class GovSpider(scrapy.Spider):name = 'gov_spider'start_urls = ['http://www.stats.gov.cn/tjsj/zxfb/']def parse(self, response):for row in response.css('table.data-table tr'):yield GovDataItem({'quarter': row.xpath('td[1]/text()').get(),'gdp': row.xpath('td[2]/text()').get(),'growth_rate': row.xpath('td[3]/text()').get()})

输出示例

[{"quarter": "2023-Q1", "gdp": "284997", "growth_rate": "4.5%"},{"quarter": "2023-Q2", "gdp": "308038", "growth_rate": "6.3%"}
]

案例2:动态API逆向工程

目标:破解某电商商品列表加密参数

# 逆向分析加密参数
import requests
from bs4 import BeautifulSoupdef get_token():response = requests.get('https://api.example.com/init')soup = BeautifulSoup(response.text, 'html.parser')return soup.find('script')['data-token']# 在Scrapy中使用
class ApiSpider(scrapy.Spider):def parse(self, response):token = get_token()yield scrapy.FormRequest(url="https://api.example.com/data",formdata={'token': token, 'page': '1'},callback=self.parse_data)

响应示例

{"data": [{"id": 1001, "name": "智能手机", "price": 2999},{"id": 1002, "name": "笔记本电脑", "price": 8999}]
}

扩展思考

1. 法律合规设计

# robots.txt遵守中间件
class RobotsTxtMiddleware:def process_request(self, request, spider):if not spider.allowed_domains:return# 校验robots协议rp = RobotFileParser()rp.set_url(f"http://{spider.allowed_domains[0]}/robots.txt")rp.read()if not rp.can_fetch("*", request.url):spider.logger.warning(f"Blocked by robots.txt: {request.url}")return scrapy.Request(url=request.url, dont_filter=True, callback=lambda _: None)

2. 反爬虫对抗测试框架

测试方案:模拟IP封禁、验证码场景

# 使用Selenium测试反爬
from selenium import webdriver
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
driver.get("https://example.com/protected-page")# 检测是否出现验证码
if "验证码" in driver.page_source:print("触发验证码防护")# 调用第三方验证码识别APIcaptcha = solve_captcha(driver.find_element(By.ID, "captcha-img"))driver.find_element(By.ID, "captcha-input").send_keys(captcha)

总结

本文构建了完整的Scrapy技术体系:

  1. 中间件系统:实现请求指纹管理、动态渲染、代理切换
  2. 增量机制:通过Redis+BloomFilter实现百亿级URL去重
  3. 合规设计:内置robots协议校验与速率限制
  4. 分布式扩展:支持跨服务器协同爬取

📌 实战建议:

  • 优先使用scrapy shell调试Selector
  • 动态页面优先尝试逆向API而非直接渲染
  • 企业级项目建议结合Scrapy-Redis+Gerapy分布式部署

相关阅读:No19-时间序列预测 | No21-微服务架构设计

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31446.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot整合WebSocket

目录 ?引言 1.WebSocket 基础知识 ?1.1 什么是 WebSocket? ?1.2 WebSocket 的应用场景 ?2.Spring Boot WebSocket 整合步骤 2.1 创建 Spring Boot 项目 2.2 添加 Maven 依赖 2.3 配置 WebSocket 2.4 创建 WebSocket 控制器 2.5 创建前端页面 引言 在…

《OkHttp:工作原理 拦截器链深度解析》

目录 一、OKHttp 的基本使用 1. 添加依赖 2. 发起 HTTP 请求 3. 拦截器(Interceptor) 4. 高级配置 二、OKHttp 核心原理 1. 责任链模式(Interceptor Chain) 2. 连接池(ConnectionPool) 3. 请求调度…

【前端】BOM DOM

两天更新完毕,建议关注收藏点赞 友情链接: HTML&CSS&LESS&Bootstrap&Emmet Axios & AJAX & Fetch BOM DOM 待整理 js2 Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM)。官方文档点击跳转 目录 BOMDOM…

产品需求分析-概览

产品需求分析-概览 产品需求分析(上)-理论流程 需求产生(来源) 公司内部(老板、其他部门同事)产品经理自己(策划、挖掘)外部(用户、客户、伙伴) 需求分类 功能类数据类运营类体验类设计类 需求决策 战略定位产品定位用户需求 需求分位:四象限定位法 重要又…

小程序事件系统 —— 32 事件系统 - 事件分类以及阻止事件冒泡

在微信小程序中,事件分为 冒泡事件 和 非冒泡事件 : 冒泡事件:当一个组件的事件被触发后,该事件会向父节点传递;(如果父节点中也绑定了一个事件,父节点事件也会被触发,也就是说子组…

spring6概述

spring6 1、概述 1.1、Spring是什么?1.2、Spring 的狭义和广义1.3、Spring Framework特点1.4、Spring模块组成1.5、Spring6特点 1.5.1、版本要求 2.2、构建模块2.3、程序开发 2.3.1、引入依赖2.3.3、创建配置文件2.3.4、创建测试类测试2.3.5、运行测试程序 2.4、程序…

【Linux docker】关于docker启动出错的解决方法。

无论遇到什么docker启动不了的问题 就是 查看docker状态sytemctl status docker查看docker日志sudo journalctl -u docker.service查看docker三个配置文件(可能是配置的时候格式错误):/etc/docker/daemon.json(如果存在&#xf…

CTF网络安全题库 CTF网络安全大赛答案

此题解仅为部分题解,包括: 【RE】:①Reverse_Checkin ②SimplePE ③EzGame 【Web】①f12 ②ezrunner 【Crypto】①MD5 ②password ③看我回旋踢 ④摩丝 【Misc】①爆爆爆爆 ②凯撒大帝的三个秘密 ③你才是职业选手 一、 Re ① Reverse Chec…

1.1 双指针专题:移动零(easy)

一、题目链接 283. 移动零 二、题目描述 给定⼀个数组 nums ,编写⼀个函数将所有 0 移动到数组的末尾,同时保持⾮零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进⾏操作。 ⽰例 1: 输⼊: nums [0,1,0,3,12] 输出: […

STM32如何精准控制步进电机?

在工业自动化、机器人控制等场合,步进电机以其高精度、开环控制的特性得到了广泛应用。而在嵌入式系统中,使用STM32进行步进电机的精确控制,已成为开发者的首选方案之一。 本文将从嵌入式开发者的角度,深入探讨如何基于STM32 MCU…

Android Studio右上角Gradle 的Task展示不全

Android Studio 版本如下:Android Studio lguana|2023.21, 发现Gradle 的Tasks阉割严重,如下图,只显示一个other 解决方法如下:**Setting>Experimental>勾选Configure all gradle tasks during Gradle Sync(this can make…

华为hcia——Datacom实验指南——三层交换和ARP的工作原理

什么是三层交换 三层交换是指连接在同一台三层交换机上,不同vlan用户,不同网段ip,通过vlanif接口进行数据交换。 什么是ARP协议 通过网络层的ip地址解析成数据链路层的mac地址。 说白了就是通过目标ip地址去问他对应的mac地址是多少。 A…

【互联网性能指标】QPS/TPS/PV/UV/IP/GMV/DAU/MAU/RPS

📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、…

Spring(七)AOP-代理模式

目录 代理模式 一 静态代理 一、核心作用 二、使用场景 二 动态代理 一、核心作用 二、使用场景 具体实现:(初始) 具体实现:(改进) 一、核心业务逻辑 1. 接口 MathCalculator 2. 实现类 MathCa…

AI革命编程学习:Python语法速通与高阶突破全实战(第二部分:AI辅助调试与高阶编程)

只要编程,代码错误和有问题肯定是难免,更何况还是全AI生成代码,是否符合我们的要求与预期,以及代码是否有逻辑错误,是否有代码错误。下面我们继续这一部分,代码调试、代码修复等基本过程。 一、代码调试 …

脚本学习(1)验证目录自动化生成脚本

1、脚本介绍 旨在一键创建符合IC验证规范的目录结构,避免手动创建目录和文件的重复劳动。 优点:模块级验证目录可一键创建,代码简单易懂,可复用性高。 缺点:子系统或系统级不适用。 2、生成的目录结构 /home/user…

【C#实现手写Ollama服务交互,实现本地模型对话】

前言 C#手写Ollama服务交互,实现本地模型对话 最近使用C#调用OllamaSharpe库实现Ollama本地对话,然后思考着能否自己实现这个功能。经过一番查找,和查看OllamaSharpe源码发现确实可以。其实就是开启Ollama服务后,发送HTTP请求&a…

【十四】Golang 接口

💢欢迎来到张胤尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 接口接口定义接口初始化接口嵌套空接口存储任意类…

Spark(8)配置Hadoop集群环境-使用脚本命令实现集群文件同步

一.hadoop的运行模式 二.scp命令————基本使用 三.scp命令———拓展使用 四.rsync远程同步 五.xsync脚本集群之间的同步 一.hadoop的运行模式 hadoop一共有如下三种运行方式: 1. 本地运行。数据存储在linux本地,测试偶尔用一下。我们上一节课使用…

基于Django的协同过滤算法养老新闻推荐系统的设计与实现

基于Django的协同过滤算法养老新闻推荐系统(可改成普通新闻推荐系统使用) 开发工具和实现技术 Pycharm,Python,Django框架,mysql8,navicat数据库管理工具,vue,spider爬虫&#xff0…