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

Python爬虫案例:Scrapy+XPath解析当当网网页结构

引言

在当今大数据时代,网络爬虫已成为获取互联网信息的重要工具。作为Python生态中最强大的爬虫框架之一,Scrapy凭借其高性能、易扩展的特性受到开发者广泛青睐。本文将详细介绍如何利用Scrapy框架结合XPath技术解析当当网的商品页面结构,实现一个完整的电商数据爬取案例。

一、Scrapy框架概述

Scrapy是一个为了爬取网站数据、提取结构性数据而编写的应用框架,可以广泛应用于数据挖掘、监测和自动化测试等领域。其架构设计基于Twisted异步网络框架,具有以下核心组件:

  • 引擎(Engine): 控制数据流在系统中的所有组件流动
  • 调度器(Scheduler): 从引擎接收请求并排队
  • 下载器(Downloader): 获取网页并返回给爬虫
  • 爬虫(Spiders): 用户编写的解析响应和提取数据的类
  • 项目管道(Item Pipeline): 处理被爬虫提取出来的项目

二、项目环境搭建

在开始之前,我们需要安装必要的Python库

创建Scrapy项目:

三、当当网页面结构分析

在编写爬虫之前,我们需要先分析当当网的页面结构。以图书商品页为例(如:http://product.dangdang.com/29116046.html),主要包含以下信息:%EF%BC%8C%E4%B8%BB%E8%A6%81%E5%8C%85%E5%90%AB%E4%BB%A5%E4%B8%8B%E4%BF%A1%E6%81%AF%EF%BC%9A)

  1. 商品标题
  2. 商品价格
  3. 作者信息
  4. 出版社信息
  5. 出版时间
  6. 商品详情
  7. 用户评价

使用浏览器开发者工具(F12)可以查看页面HTML结构,为后续XPath编写做准备。

四、定义数据模型

**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">items.py</font>**中定义我们要抓取的数据字段:

import scrapyclass DangdangItem(scrapy.Item):title = scrapy.Field()       # 商品标题price = scrapy.Field()       # 商品价格author = scrapy.Field()      # 作者publisher = scrapy.Field()   # 出版社publish_date = scrapy.Field() # 出版日期detail = scrapy.Field()      # 商品详情comments = scrapy.Field()    # 用户评价数量isbn = scrapy.Field()        # ISBN号url = scrapy.Field()         # 商品链接

五、编写爬虫核心代码

**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">spiders/dd_spider.py</font>**中编写爬虫逻辑:

import scrapy
from dangdang.items import DangdangItem
from scrapy.http import Requestclass DdSpiderSpider(scrapy.Spider):name = 'dd_spider'allowed_domains = ['dangdang.com']start_urls = ['http://category.dangdang.com/cp01.54.06.00.00.00.html']  # 从图书分类页开始# 解析分类页,获取商品详情页链接def parse(self, response):book_links = response.xpath('//a[@name="itemlist-picture"]/@href').extract()for link in book_links:yield Request(url=link, callback=self.parse_book)# 处理分页next_page = response.xpath('//li[@class="next"]/a/@href').extract_first()if next_page:yield Request(url=next_page, callback=self.parse)# 解析商品详情页def parse_book(self, response):item = DangdangItem()# 使用XPath提取数据item['title'] = response.xpath('//div[@class="name_info"]/h1/@title').extract_first()item['price'] = response.xpath('//p[@id="dd-price"]/text()').extract_first().strip()# 作者信息可能有多人authors = response.xpath('//span[@id="author"]/a/text()').extract()item['author'] = ' '.join(authors) if authors else Noneitem['publisher'] = response.xpath('//a[@dd_name="出版社"]/text()').extract_first()item['publish_date'] = response.xpath('//div[@class="messbox_info"]/span[2]/text()').extract_first()# 处理详情信息details = []detail_nodes = response.xpath('//div[@class="detail_content"]//text()').extract()for detail in detail_nodes:if detail.strip():details.append(detail.strip())item['detail'] = '\n'.join(details)item['comments'] = response.xpath('//a[@dd_name="单品页点击评论"]/text()').extract_first()item['isbn'] = response.xpath('//div[@class="messbox_info"]/span[last()]/text()').extract_first()item['url'] = response.urlyield item

六、XPath选择器详解

XPath是一种在XML文档中查找信息的语言,同样适用于HTML文档。上述代码中我们使用了多种XPath表达式:

  1. **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">//a[@name="itemlist-picture"]/@href</font>** - 选择所有name属性为"itemlist-picture"的a标签的href属性
  2. **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">//div[@class="name_info"]/h1/@title</font>** - 选择class为"name_info"的div下的h1标签的title属性
  3. **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">//span[@id="author"]/a/text()</font>** - 选择id为"author"的span下的所有a标签的文本
  4. **<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">//div[@class="messbox_info"]/span[2]/text()</font>** - 选择class为"messbox_info"的div下的第二个span标签的文本

XPath选择器比正则表达式更直观,更适合处理HTML文档的层次结构。

七、处理反爬机制

当当网和其他电商网站一样,都有反爬虫机制。我们需要在**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">settings.py</font>**中进行一些配置:

python

# 代理配置
PROXY_HOST = "www.16yun.cn"
PROXY_PORT = "5445"
PROXY_USER = "16QMSOML"
PROXY_PASS = "280651"# 设置下载延迟
DOWNLOAD_DELAY = 2# 启用AutoThrottle扩展
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 5
AUTOTHROTTLE_MAX_DELAY = 60# 设置User-Agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'# 启用Cookies
COOKIES_ENABLED = True# 配置中间件
DOWNLOADER_MIDDLEWARES = {'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,'scrapy_user_agents.middlewares.RandomUserAgentMiddleware': 400,'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 100,'dangdang.middlewares.ProxyMiddleware': 110,  # 自定义代理中间件
}

八、数据存储处理

**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">pipelines.py</font>**中实现数据存储逻辑,这里以MongoDB为例:

python

import pymongoclass MongoDBPipeline(object):def __init__(self, mongo_uri, mongo_db):self.mongo_uri = mongo_uriself.mongo_db = mongo_db@classmethoddef from_crawler(cls, crawler):return cls(mongo_uri=crawler.settings.get('MONGO_URI'),mongo_db=crawler.settings.get('MONGO_DATABASE', 'dangdang'))def open_spider(self, spider):self.client = pymongo.MongoClient(self.mongo_uri)self.db = self.client[self.mongo_db]def close_spider(self, spider):self.client.close()def process_item(self, item, spider):collection_name = item.__class__.__name__self.db[collection_name].insert_one(dict(item))return item

**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">settings.py</font>**中启用管道并配置MongoDB连接:

python

ITEM_PIPELINES = {'dangdang.pipelines.MongoDBPipeline': 300,
}MONGO_URI = 'mongodb://localhost:27017'
MONGO_DATABASE = 'dangdang'

九、高级技巧与优化

  1. 分布式爬取:使用Scrapy-Redis实现分布式爬虫
  2. 动态内容处理:对于JavaScript渲染的内容,可以使用Splash或Selenium中间件
  3. 增量爬取:通过记录已爬取的URL实现增量爬取
  4. 异常处理:增强爬虫的健壮性

结语

本文详细介绍了使用Scrapy框架和XPath技术爬取当当网商品信息的全过程。通过这个案例,我们学习了如何分析网页结构、编写XPath选择器、处理反爬机制以及存储爬取结果。Scrapy的强大功能结合XPath的灵活选择能力,可以应对大多数网页爬取需求。

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

相关文章:

  • Lua(模块与包)
  • 【docker | 部署 】Jetson Orin与AMD平台容器化部署概述
  • Java 实现 B/S 架构详解:从基础到实战,彻底掌握浏览器/服务器编程
  • 前端性能新纪元:Rust + WebAssembly 如何在浏览器中实现10倍性能提升(以视频处理为例)
  • 【RAG优化】RAG应用中图文表格混合内容的终极检索与生成策略
  • VUE的学习
  • iOS WebView 加载失败与缓存刷新问题排查实战指南
  • 医疗行业新变革:AR 培训系统助力手术培训精准高效​
  • Oracle国产化替代:一线DBA的技术决策突围战
  • 华为OpenStack架构学习9篇 连载—— 01 OpenStack架构介绍【附全文阅读】
  • 【C++】使用箱线图算法剔除数据样本中的异常值
  • Vue 项目中的组件引用如何实现,依赖组件间的数据功能交互及示例演示
  • CIRL:因果启发的表征学习框架——从域泛化到奖励分解的因果革命
  • Spring MVC中常用注解_笔记
  • 【Linux】linux基础开发工具(一) 软件包管理器yum、编辑器vim使用与相关命令
  • MCU(微控制器)中的高电平与低电平?
  • 实战演练11:生成式对话机器人(Bloom)
  • 输电线路微气象在线监测装置:保障电网安全的科技屏障
  • [网安工具] 自动化威胁检测工具 —— D 盾 · 使用手册
  • 多模态LLM/Diffusion推理加速
  • 11.2 yolov8用自己的数据集训练语义分割模型
  • Android Camera createCaptureSession
  • Mysql命令show processlist
  • 成品电池综合测试仪:保障电池品质与安全的核心工具|深圳鑫达能
  • 聚观早报 | 猿编程推动中美青少年AI实践;华为Pura 80数字版售价公布;iPhone 17 Air电池曝光
  • J2EE模式---组合实体模式
  • ollama无法拉取模型导致报错
  • Linux724 逻辑卷挂载;挂载点扩容;逻辑卷开机自启
  • 噪声环境下的数据驱动预测控制:提升抗测量噪声干扰能力
  • Python桌面版数独(五版)-优化选择模式触发新棋盘生成