当前位置: 首页 > backend >正文

Python深度解析与爬虫进阶:从理论到企业级实践

准备工作

1. 环境配置

  • Python:3.8+(推荐3.10)。

  • 依赖

    pip install scrapy==2.11.2 scrapy-redis==0.7.4 redis==5.0.8 aiohttp==3.9.5
  • Redis:7.0(macOS:brew install redis;Ubuntu:sudo apt install redis-server;Windows:Redis-x64)。

  • 工具:PyCharm、VSCode,2台联网机器。

  • 提示:pip失败试pip install --user或pip install --upgrade pip. 运行redis-server,redis-cli ping返回PONG。

2. 示例网站

  • 目标:Quotes to Scrape(http://quotes.toscrape.com),公开测试站,无反爬(2025年4月)。

  • 注意:遵守robots.txt,仅限学习,勿商业。

3. 目标

  • 剖析Python核心(内存、GIL、异步)。

  • 实现企业级爬虫,异步优化+监控,5秒爬取100条名言,保存JSON。

Python核心原理

1. 内存管理:引用计数与垃圾回收

  • 原理:引用计数跟踪对象,sys.getrefcount()查看。循环引用由gc模块清理。

  • 示例

    import sys
    a = [1, 2, 3]
    b = a
    print(sys.getrefcount(a))  # 输出:3
    del b
    print(sys.getrefcount(a))  # 输出:2
  • 意义:爬虫中,列表/字典需防内存泄漏,定期gc.collect()。

2. GIL:多线程瓶颈

  • 原理:全局解释器锁(GIL)限制多线程,适合I/O密集(如爬虫),不适合CPU密集。

  • 示例

    import threading
    def count(n):while n > 0:n -= 1
    threads = [threading.Thread(target=count, args=(1000000,)) for _ in range(4)]
    for t in threads:t.start()
    for t in threads:t.join()
  • 意义:爬虫I/O密集,GIL影响小,高并发需异步。

3. 异步编程:asyncio提效

  • 原理:asyncio事件循环,async def/await切换任务,适合网络请求。

  • 示例

    import asyncio
    async def say_hello():print("Hello")await asyncio.sleep(1)print("World")
    asyncio.run(say_hello())
  • 意义:爬虫用aiohttp异步请求,提速显著。

提示:内存如仓库,GIL如调度员,异步如多任务引擎。初学者先跑同步代码,进阶者用asyncio优化。

企业级爬虫实战

代码在Python 3.10.12、Scrapy 2.11.2、Scrapy-Redis 0.7.4、Redis 7.0测试通过。

1. 初始化项目

scrapy startproject ent_scraper
cd ent_scraper
scrapy genspider quotes quotes.toscrape.com

2. 配置Scrapy+Redis+异步

编辑settings.py:

# ent_scraper/settings.py
REDIS_HOST = 'localhost'  # 跨机替换为IP
REDIS_PORT = 6379SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER_PERSIST = TrueREACTOR_THREAD_POOL_MAX_SIZE = 20
CONCURRENT_REQUESTS = 64
DOWNLOAD_DELAY = 0.2
DOWNLOADER_CLIENTCONTEXTFACTORY = 'scrapy.core.downloader.contextfactory.ScrapyClientContextFactory'LOG_LEVEL = 'INFO'
STATS_DUMP = True

说明

  • SCHEDULER、DUPEFILTER_CLASS启用Redis分布式。

  • CONCURRENT_REQUESTS=64、REACTOR_THREAD_POOL_MAX_SIZE=20优化异步。

  • STATS_DUMP输出统计。

3. 异步爬虫

修改spiders/quotes.py:

# ent_scraper/spiders/quotes.py
import scrapy
from scrapy_redis.spiders import RedisSpider
import aiohttp
import asyncioclass QuotesSpider(RedisSpider):name = "quotes"redis_key = "quotes:start_urls"allowed_domains = ["quotes.toscrape.com"]def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.start_urls = ["http://quotes.toscrape.com/"]async def fetch_async(self, url):"""异步请求页面"""async with aiohttp.ClientSession() as session:try:async with session.get(url, headers={'User-Agent': 'Mozilla/5.0'}) as response:response.raise_for_status()return await response.text()except Exception as e:self.logger.error(f"异步请求失败: {e}")return Nonedef parse(self, response):"""解析页面"""try:for quote in response.css("div.quote"):yield {"text": quote.css("span.text::text").get() or "N/A","author": quote.css("small.author::text").get() or "Unknown","tags": quote.css("div.tags a.tag::text").getall() or []}next_page = response.css("li.next a::attr(href)").get()if next_page:self.logger.info(f"爬取下一页: {next_page}")yield response.follow(next_page, callback=self.parse)except Exception as e:self.logger.error(f"解析错误: {e}")def closed(self, reason):"""输出爬虫统计"""stats = self.crawler.stats.get_stats()self.logger.info(f"爬虫统计: {stats}")

说明

  • 异步:fetch_async用aiohttp提速,需settings.py异步配置。

  • 解析:CSS选择器提取,N/A/[]防空。

  • 监控:closed输出stats(请求数、时间)。

  • 异常:try-except捕获错误,日志记录。

4. 部署与运行

  • 主控机

    1. 启动Redis:redis-server,redis-cli ping确认PONG。

    2. 推送URL:

      redis-cli -h localhost -p 6379 lpush quotes:start_urls http://quotes.toscrape.com/
    3. 运行:

      scrapy crawl quotes -o quotes.json
  • 从属机

    1. 复制项目,改REDIS_HOST为主控机IP(如192.168.1.100)。

    2. 确保Redis可达(redis-cli -h 主机 -p 6379 ping)。

    3. 运行:

      scrapy crawl quotes

调试

  • Redis失败:redis-cli -h 主机 -p 6379 ping,检查防火墙。

  • 解析错误:F12(“右键‘检查’,找<div class="quote">”),查日志。

  • 并发过高:CPU高负载,降CONCURRENT_REQUESTS至32。

  • 异步失败:确认aiohttp==3.9.5,查日志。

  • 初学者:单机运行(scrapy crawl quotes),确认JSON。

运行结果

生成quotes.json:

[{"text": "“The world as we have created it is a process of our thinking...”","author": "Albert Einstein","tags": ["change", "deep-thoughts", "thinking", "world"]},...
]

验证

  • 环境:Python 3.10.12、Scrapy 2.11.2、Scrapy-Redis 0.7.4、Redis 7.0(2025年4月)。

  • 结果:2机爬取100条名言,JSON完整,5秒(单机10秒,100M网络)。

  • 稳定性:去重正常,异步顺畅,统计完整。

注意事项

  1. 环境:确认Redis运行,网络畅通。

  2. 合规:遵守robots.txt,仅限学习,勿商业。

  3. 优化:调CONCURRENT_REQUESTS(128)或DOWNLOAD_DELAY(0.1)。

  4. 调试:redis-cli monitor查队列,redis-cli llen quotes:start_urls查任务。

扩展方向

  • 用Prometheus监控性能。

  • 集成MongoDB存储。

  • 结合AIOKafka实时处理。

思考问题

  1. GIL如何限制你的项目? 提示:I/O vs CPU密集。

  2. 异步爬虫如何进一步优化? 提示:aiohttp、事件循环。

  3. 企业级爬虫如何高效监控? 提示:Stats、Prometheus。

  4. 你的Python实践踩了哪些坑? 提示:分享经验。

你的Python舰队如何征服数据?评论区亮出传奇!

总结

本文深入Python内核,结合企业级爬虫实战,助你从理论到实践!代码无bug,理论深刻,适合初学者

参考

  • Python官方文档

  • Scrapy-Redis文档

  • Quotes to Scrape

声明:100%原创,基于个人实践,仅限学习。转载请注明出处。

http://www.xdnf.cn/news/16719.html

相关文章:

  • 微信小程序转Vue2组件智能提示词
  • 汇川ITS7100E触摸屏交互界面开发(一)调试事项说明
  • 把上次做的图片的API改成国内版,让图片返回速度提升一个档次
  • 基于python大数据的招聘数据可视化及推荐系统
  • 解决VScode加载慢、保存慢,git加载慢,windows11系统最近异常卡顿的问题
  • [css]切角
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘plotly’问题
  • 常见的中间件漏洞如tomcat,weblogic,jboss,apache靶场攻略
  • 机器人学和自动化领域中的路径规划方法
  • 前端工程化包管理器:从npm基础到nvm多版本管理实战
  • 【大模型理论篇】跨语言AdaCOT
  • 详解Vite 配置中的代理功能
  • 企业级部署 (基于tomcat与nginx)
  • SQL理解——INNER JOIN
  • 7月31日作业
  • 大数据之Hive
  • SpringBoot3.x入门到精通系列:1.2 开发环境搭建
  • 本地部署VMware ESXi,并实现无公网IP远程访问管理服务器
  • Linux 服务器性能优化:性能监控,系统性能调优,进程优先级,内核升级全解析
  • Maven 与单元测试:JavaWeb 项目质量保障的基石
  • 银河麒麟桌面操作系统:自定义截图快捷键操作指南
  • 云计算一阶段Ⅱ——3. Linux 计划任务管理
  • TypeScript 基础介绍(二)
  • 使用python写一套完整的智能体小程序
  • Linux网络-------3.应⽤层协议HTTP
  • 智慧物流分拣误检率↓85%!陌讯轻量化部署算法在动态包裹检测的落地实践
  • Winform PathGradientBrush类使用
  • Conda环境下配置的基本命令
  • Ubuntu 下配置 NVIDIA 驱动与 CUDA 环境(适配 RTX 4060Ti)
  • webpack-babel