在当今大数据时代,网络爬虫已成为获取互联网信息的重要工具。作为Python生态中最强大的爬虫框架之一,Scrapy凭借其高性能、易扩展的特性受到开发者广泛青睐。本文将详细介绍如何利用Scrapy框架结合XPath技术解析当当网的商品页面结构,实现一个完整的电商数据爬取案例。
Scrapy是一个为了爬取网站数据、提取结构性数据而编写的应用框架,可以广泛应用于数据挖掘、监测和自动化测试等领域。其架构设计基于Twisted异步网络框架,具有以下核心组件:
在开始之前,我们需要安装必要的Python库
创建Scrapy项目:
在编写爬虫之前,我们需要先分析当当网的页面结构。以图书商品页为例
使用浏览器开发者工具(F12)可以查看页面HTML结构,为后续XPath编写做准备。
在items.py
中定义我们要抓取的数据字段:
import scrapy
class 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() # 商品链接
在spiders/dd_spider.py
中编写爬虫逻辑:
import scrapy
from dangdang.items import DangdangItem
from scrapy.http import Request
class 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 None
item['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.url
yield item
XPath是一种在XML文档中查找信息的语言,同样适用于HTML文档。上述代码中我们使用了多种XPath表达式:
//a[@name="itemlist-picture"]/@href
- 选择所有name属性为"itemlist-picture"的a标签的href属性//div[@class="name_info"]/h1/@title
- 选择class为"name_info"的div下的h1标签的title属性//span[@id="author"]/a/text()
- 选择id为"author"的span下的所有a标签的文本//div[@class="messbox_info"]/span[2]/text()
- 选择class为"messbox_info"的div下的第二个span标签的文本XPath选择器比正则表达式更直观,更适合处理HTML文档的层次结构。
当当网和其他电商网站一样,都有反爬虫机制。我们需要在settings.py
中进行一些配置:
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, # 自定义代理中间件
}
在pipelines.py
中实现数据存储逻辑,这里以MongoDB为例:
python
import pymongo
class MongoDBPipeline(object):
def __init__(self, mongo_uri, mongo_db):
self.mongo_uri = mongo_uri
self.mongo_db = mongo_db
@classmethod
def 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
在settings.py
中启用管道并配置MongoDB连接:
python
ITEM_PIPELINES = {
'dangdang.pipelines.MongoDBPipeline': 300,
}
MONGO_URI = 'mongodb://localhost:27017'
MONGO_DATABASE = 'dangdang'
本文详细介绍了使用Scrapy框架和XPath技术爬取当当网商品信息的全过程。通过这个案例,我们学习了如何分析网页结构、编写XPath选择器、处理反爬机制以及存储爬取结果。Scrapy的强大功能结合XPath的灵活选择能力,可以应对大多数网页爬取需求。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。