爬虫修炼手册,Python爬虫学习入门Scrapy
ccwgpt 2025-05-14 12:19 18 浏览 0 评论
爬虫就如同江湖中的神秘侠客,应运而生,成为了我们获取数据的得力助手。爬虫,正式名称是网络爬虫(Web Crawler),也被叫做网页蜘蛛、网络机器人 ,它是一段神奇的计算机代码,能够自动在互联网的信息海洋中穿梭,抓取我们需要的数据。简单来说,爬虫就像是一个不知疲倦的信息采集员,按照我们设定的规则,自动访问网页,然后把网页中的文字、图片、链接等各种数据提取出来。
邂逅 Scrapy 大侠
在爬虫的江湖中,Scrapy 无疑是一位备受瞩目的大侠。它是用 Python 编写的一个快速、高层次的屏幕抓取和 Web 抓取框架,专为爬取网站数据、提取结构性数据而设计,在数据挖掘、监测和自动化测试等领域大显身手 。
Scrapy 之所以如此厉害,首先得益于它使用了 Twisted 异步网络框架。这就好比给爬虫装上了一双飞速奔跑的翅膀,能够异步处理多个请求,大大加快了下载速度,使得它在面对大量网页时,也能高效地完成数据抓取任务。举个例子,当我们需要从一个包含众多页面的电商网站上抓取商品信息时,Scrapy 可以同时向多个页面发送请求,而不需要像传统的同步方式那样,一个一个地等待请求完成,从而大大缩短了整个抓取过程的时间。
其次,Scrapy 内置了强大的 Selector(选择器),支持 XPath 和 CSS 选择器。这就如同给了我们一把精准的手术刀,能够在复杂的 HTML 和 XML 文档中,准确地定位和提取我们需要的数据。比如,我们想要提取网页中所有商品的名称和价格,使用 Scrapy 的 Selector,通过编写简单的 XPath 或 CSS 表达式,就能轻松地将这些数据从网页的代码中提取出来,而无需手动去逐行分析和筛选。
修炼第一步:项目结构
项目文件结构:
scrapy.cfg:这是项目的配置文件,主要用于部署项目到 Scrapy 服务器(如 Scrapyd)时的配置。虽然在日常开发中,我们可能不会频繁修改这个文件,但它对于项目的部署和管理是非常重要的。
项目同名文件夹(如 my_scrapy_project):这个文件夹是项目的核心代码所在,包含了多个重要的 Python 文件和一个spiders文件夹。它是整个项目的逻辑组织中心,所有与爬虫相关的代码、配置和数据处理逻辑都在这里定义和实现。
__init__.py:这是一个空文件,其作用是将所在的文件夹标记为一个 Python 包,这样 Python 解释器就可以识别并导入该文件夹中的模块。
items.py:在这个文件中,定义了爬虫要抓取的数据结构,也就是Item。Item类似于一个容器,用于存储从网页中提取的数据。比如我们要抓取电商网站上的商品信息,就可以在items.py中定义ProductItem,包含name(商品名称)、price(价格)、description(商品描述)等字段 。
middlewares.py:中间件文件,用于处理请求和响应的中间过程。我们可以在这里定义各种中间件,如用户代理中间件、代理 IP 中间件等。通过自定义用户代理中间件,可以在每个请求中随机更换用户代理,模拟不同的浏览器访问,从而提高爬虫的隐蔽性,降低被反爬虫机制检测到的风险。
pipelines.py:数据管道文件,主要用于处理爬虫提取到的数据。在这里可以进行数据清洗、存储到数据库、保存到文件等操作。比如,将爬取到的文章数据存储到 MySQL 数据库中,就可以在pipelines.py中编写相应的代码来实现数据的插入操作。
settings.py:项目的设置文件,包含了项目的各种配置参数,如爬虫的并发请求数、下载延迟、用户代理、启用的管道和中间件等。这些配置参数可以根据项目的需求进行调整,以优化爬虫的性能和行为。例如,通过设置DOWNLOAD_DELAY来控制下载页面的时间间隔,避免对目标网站造成过大的压力,从而防止被封禁 IP。
spiders文件夹:这个文件夹用于存放爬虫代码。每个爬虫都是一个 Python 类,继承自scrapy.Spider类,在这个文件夹中可以创建多个爬虫类,每个爬虫类负责从特定的网站或网页中抓取数据。例如,我们可以创建一个NewsSpider类来抓取新闻网站的文章,一个ImageSpider类来抓取图片网站的图片链接等。每个爬虫类都需要定义name(爬虫名称)、start_urls(起始 URL 列表)和parse方法(用于解析响应数据)等。
深入修炼:爬虫核心构建
(一)目标锁定:items.py
在 Scrapy 项目中,items.py文件就像是我们的寻宝地图,它定义了我们要从网页中抓取的数据结构,也就是Item。每个Item类都继承自scrapy.Item ,并定义了一系列的字段(Field),这些字段就是我们要抓取的数据项。
以爬取知乎用户信息为例,我们在items.py中定义如下:
import scrapy
class ZhihuUserItem(scrapy.Item):
# 用户ID
user_id = scrapy.Field()
# 用户名
username = scrapy.Field()
# 性别
gender = scrapy.Field()
# 关注数
following_count = scrapy.Field()
# 粉丝数
follower_count = scrapy.Field()
在这个例子中,我们定义了一个ZhihuUserItem类,它包含了user_id、username、gender、following_count和follower_count等字段,这些字段就是我们想要从知乎用户页面中抓取的信息。通过这样的定义,我们就明确了爬虫的目标,后续在爬虫代码中,就可以按照这个结构来提取和存储数据。
(二)爬虫出鞘:spiders
spiders文件夹是存放爬虫代码的地方,每个爬虫都是一个 Python 类,继承自scrapy.Spider类。在这个类中,我们需要定义爬虫的名称、起始 URL 列表以及解析响应数据的方法。
以爬取知乎用户信息为例,我们创建一个ZhihuSpider类,代码如下:
import scrapy
class ZhihuSpider(scrapy.Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['https://www.zhihu.com/people/your_username']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url, callback=self.parse)
def parse(self, response):
item = ZhihuUserItem()
item['user_id'] = response.css('meta[itemprop="identifier"]::attr(content)').get()
item['username'] = response.css('span.ProfileHeader-name::text').get()
gender = response.css('span.ProfileHeaderGender-icon::attr(class)').get()
item['gender'] = '男' if 'male' in gender else '女' if 'female' in gender else '未知'
item['following_count'] = response.css('a.Following-statusItem--following::text').get()
item['follower_count'] = response.css('a.Following-statusItem--followers::text').get()
yield item
在这个爬虫类中:
name属性是爬虫的唯一标识,在运行爬虫时会用到,比如scrapy crawl zhihu ,这里的zhihu就是name的值。
allowed_domains指定了允许爬虫访问的域名,防止爬虫访问到其他不相关的网站,避免浪费资源和违反规定。
start_urls是爬虫的起始 URL 列表,爬虫会从这些 URL 开始发送请求。
start_requests方法生成初始的请求对象,它遍历start_urls列表,为每个 URL 生成一个scrapy.Request对象,并指定回调函数为parse方法。
parse方法是处理响应数据的核心方法,它接收下载器返回的响应对象response ,通过 CSS 选择器从响应的 HTML 中提取我们需要的数据,填充到ZhihuUserItem对象中,并使用yield返回该对象,这样数据就会被传递到后续的处理流程中。
(三)管道守护:pipelines.py
pipelines.py文件用于处理爬虫提取到的数据,它就像是一个数据加工厂,对爬取到的数据进行清洗、存储等操作。每个数据管道组件都是一个 Python 类,需要实现process_item方法,该方法接收一个Item对象和一个Spider对象作为参数,并返回一个Item对象或抛出DropItem异常。
以将爬取到的知乎用户信息存储到 MongoDB 为例,我们在pipelines.py中编写如下代码:
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_DB')
)
def open_spider(self, spider):
self.client = pymongo.MongoClient(self.mongo_uri)
self.db = self.client[self.mongo_db]
def process_item(self, item, spider):
self.db['zhihu_users'].insert_one(dict(item))
return item
def close_spider(self, spider):
self.client.close()
在这个管道类中:
__init__方法用于初始化管道,接收mongo_uri和mongo_db两个参数,分别表示 MongoDB 的连接地址和数据库名称。
from_crawler方法是一个类方法,用于从Crawler对象中获取设置信息,创建管道实例。
open_spider方法在爬虫启动时被调用,用于建立与 MongoDB 的连接。
process_item方法是核心处理方法,它将接收到的Item对象转换为字典,并插入到 MongoDB 的zhihu_users集合中,然后返回Item对象,以便后续的管道组件继续处理。
close_spider方法在爬虫关闭时被调用,用于关闭与 MongoDB 的连接。
同时,我们还需要在settings.py中配置启用这个管道,并设置相关的 MongoDB 连接信息:
ITEM_PIPELINES = {
'your_project_name.pipelines.MongoDBPipeline': 300,
}
MONGO_URI = 'mongodb://localhost:27017'
MONGO_DB = 'your_database_name'
在上述配置中,ITEM_PIPELINES字典定义了启用的管道及其优先级,数值越小优先级越高。MONGO_URI和MONGO_DB分别设置了 MongoDB 的连接地址和数据库名称。通过这样的配置,爬虫在运行时,提取到的数据就会被传递到MongoDBPipeline中进行处理,最终存储到 MongoDB 数据库中。
(四)中间件助力:middlewares.py
中间件在 Scrapy 中起着重要的作用,它可以在请求和响应的处理过程中插入自定义的逻辑。Scrapy 的中间件主要分为下载中间件(Downloader Middleware)和爬虫中间件(Spider Middleware)。
下载中间件主要用于处理引擎发送到下载器的请求和从下载器返回到引擎的响应。它可以在请求发送前修改请求头、添加代理 IP、设置 Cookies 等,也可以在响应返回后对响应进行处理,如处理重定向、处理下载错误等。例如,我们可以使用下载中间件来随机更换 User - Agent,模拟不同的浏览器访问,从而提高爬虫的隐蔽性。
爬虫中间件则主要用于处理从引擎发送到爬虫的请求和从爬虫返回到引擎的响应。它可以在请求发送到爬虫之前对请求进行处理,如添加自定义的元数据;也可以在响应返回给引擎之前对响应进行处理,如对响应数据进行预处理、过滤等。
以自定义一个随机 User - Agent 中间件为例,我们在middlewares.py中编写如下代码:
from fake_useragent import UserAgent
from scrapy import signals
class RandomUserAgentMiddleware(object):
def __init__(self):
self.ua = UserAgent(use_cache_server=False)
def process_request(self, request, spider):
request.headers.setdefault('User-Agent', self.ua.random)
在这个中间件类中:
__init__方法初始化UserAgent对象,use_cache_server=False表示不使用缓存服务器,直接从网络获取 User - Agent 列表。
process_request方法在每个请求发送前被调用,它从UserAgent对象中随机选择一个 User - Agent,并设置到请求头的User - Agent字段中,这样每个请求都会使用不同的 User - Agent,增加了爬虫的伪装性。
为了启用这个中间件,我们还需要在settings.py中进行配置:
DOWNLOADER_MIDDLEWARES = {
'your_project_name.middlewares.RandomUserAgentMiddleware': 400,
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None,
}
在上述配置中,DOWNLOADER_MIDDLEWARES字典定义了下载中间件及其优先级。我们将自定义的RandomUserAgentMiddleware添加到中间件列表中,并设置其优先级为 400 。同时,将 Scrapy 默认的UserAgentMiddleware设置为None,表示禁用它,避免与我们自定义的中间件冲突。这样,在爬虫运行时,每个请求都会使用随机的 User - Agent,从而提高爬虫的稳定性和成功率。
实战演练:爬取知乎用户信息
(一)项目准备
在开始爬取知乎用户信息之前,我们需要进行一些准备工作。首先,确保我们已经创建了一个 Scrapy 项目,并在项目中定义了items.py、spiders、pipelines.py和middlewares.py等文件。
在settings.py文件中,我们需要进行一些配置,以确保爬虫能够正常运行。例如,设置请求头以模拟真实浏览器访问,避免被反爬虫机制检测到:
DEFAULT_REQUEST_HEADERS = {
'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',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,\*/\*;q=0.8',
'Accept-Language': 'en',
}
同时,为了避免对知乎服务器造成过大压力,我们还可以设置下载延迟,让爬虫在每次请求之间等待一段时间:
DOWNLOAD_DELAY = 1
(二)代码实现
接下来,我们在spiders文件夹中创建一个爬虫类ZhihuSpider,用于爬取知乎用户信息。在这个爬虫类中,我们需要定义start_requests方法和parse方法。
start_requests方法用于生成初始的请求对象,我们从指定的知乎用户页面开始发送请求:
import scrapy
class ZhihuSpider(scrapy.Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['https://www.zhihu.com/people/your_username']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url, callback=self.parse)
parse方法用于处理响应数据,从响应中提取我们需要的用户信息。这里以提取用户的基本信息(如用户名、关注数、粉丝数等)为例:
def parse(self, response):
item = {}
item['username'] = response.css('span.ProfileHeader-name::text').get()
item['following_count'] = response.css('a.Following-statusItem--following::text').get()
item['follower_count'] = response.css('a.Following-statusItem--followers::text').get()
yield item
如果我们还需要爬取用户的关注列表,可以在parse方法中继续发送请求,获取关注列表的页面,并解析其中的用户信息。例如:
def parse(self, response):
item = {}
item['username'] = response.css('span.ProfileHeader-name::text').get()
item['following_count'] = response.css('a.Following-statusItem--following::text').get()
item['follower_count'] = response.css('a.Following-statusItem--followers::text').get()
yield item
# 爬取关注列表
following_url = response.css('a.Following-statusItem--following::attr(href)').get()
if following_url:
yield scrapy.Request(response.urljoin(following_url), callback=self.parse_following)
def parse_following(self, response):
for user in response.css('div.List-item'):
user_item = {}
user_item['username'] = user.css('a.UserLink-link::text').get()
user_item['user_url'] = user.css('a.UserLink-link::attr(href)').get()
yield user_item
# 处理分页
next_page = response.css('button.PaginationButton--next::attr(data-url)').get()
if next_page:
yield scrapy.Request(response.urljoin(next_page), callback=self.parse_following)
(三)运行与结果
在完成代码编写后,我们可以使用以下命令运行爬虫:
scrapy crawl zhihu
运行爬虫后,它会按照我们定义的规则开始爬取知乎用户信息。爬取到的数据会经过pipelines.py中定义的数据管道进行处理,例如存储到数据库中。如果我们在pipelines.py中定义了将数据存储为 JSON 格式的管道,爬取结果可能会类似如下:
[
{
"username": "张三",
"following_count": "100",
"follower_count": "500"
},
{
"username": "李四",
"following_count": "200",
"follower_count": "800"
}
]
通过以上实战演练,我们可以看到如何使用 Scrapy 框架来爬取知乎用户信息,从项目准备、代码实现到最终运行获取结果,每个步骤都紧密相连,共同构成了一个完整的数据抓取过程。在实际应用中,我们还可以根据具体需求进一步优化爬虫,如增加代理 IP、处理验证码等,以提高爬虫的稳定性和成功率。
未来展望
在学习 Scrapy 爬虫的过程中,我就像是一个初入江湖的小侠客,从对爬虫一无所知,到逐渐掌握 Scrapy 的各项技能,能够独立完成一些简单的数据抓取任务,这个过程充满了挑战,但也收获满满。通过不断地实践和摸索,我不仅学会了如何使用 Scrapy 框架来编写高效的爬虫程序,还对网页的结构、HTTP 协议以及数据处理等方面有了更深入的理解。
对于想要学习 Scrapy 爬虫的朋友们,我建议大家在掌握了基本的语法和概念之后,一定要多进行实践。可以尝试从一些简单的网站开始爬取,逐渐积累经验,然后再挑战一些更复杂的网站。同时,不要害怕遇到问题,每一个问题都是我们成长的机会,通过解决问题,我们能够更好地理解和掌握 Scrapy 的原理和应用。
未来,随着互联网的不断发展,数据的价值也将越来越高。爬虫技术作为获取数据的重要手段,也将面临更多的挑战和机遇。一方面,网站的反爬虫机制会越来越强大,这就要求我们不断地学习和探索新的反反爬虫技术,提高爬虫的稳定性和成功率;另一方面,随着大数据、人工智能等技术的发展,对数据的质量和规模也提出了更高的要求,我们需要进一步优化爬虫的性能,提高数据抓取的效率和准确性。
同时,我们也要始终牢记,在使用爬虫技术时,一定要遵守法律法规和道德规范,不要进行恶意爬取,以免给他人和社会带来不良影响。希望大家都能在 Scrapy 爬虫的学习和实践中,收获自己的宝藏秘籍,成为数据江湖中的大侠!
- 上一篇:如何入门 Python 爬虫?
- 下一篇:如何入门python爬虫?
相关推荐
- Android开发基础入门(一):UI与基础控件
-
Android基础入门前言:从今天开始,我们开始分享Android客户端开发的基础知识。一、工具指南工欲善其事必先利其器,我们首先介绍一下开发Android常用的集成开发环境。小雨在上大学期间,开发a...
- 谷歌Material Design质感设计UI开发框架
-
谷歌MaterialDesign质感设计是一个新的用户界面设计概念,即将到来的Android版本称为“AndroidL”中会使用这种设计语言。在这篇文章中,我们收集出最新的和最好的Android...
- Android主流UI开源库整理(android 开源ui)
-
前言最近老大让我整理一份Android主流UI开源库的资料,以补充公司的Android知识库。由于对格式不做特别限制,于是打算用博客的形式记录下来,方便查看、防丢并且可以持续维护、不断更新。标题隐...
- 系统工具类App的开发框架(系统开发方法工具)
-
系统工具类App的开发框架选择,很大程度上取决于目标平台(Android、iOS或两者兼有),以及对性能、系统级访问深度和开发效率的需求。由于这类App常常需要深入操作系统底层,因此原生开发框架通常是...
- 2025年vue前端框架前瞻(vue前端开发规范手册)
-
Vue是一个轻量且灵活的JavaScript框架,广受开发者喜爱,因其简单易用的API和组件化的开发方式而闻名。Vite是一个现代化的前端构建工具,以其极快的开发服务器启动速度和热模块替换...
- 前端流行框架Vue3教程:28. Vue应用
-
28.Vue应用应用实例每个Vue应用都是通过createApp函数创建一个新的应用实例main.jsimport{createApp}from'vue'import...
- 2024 Vue 最全的生态工具组合推荐指南
-
Vue3虽然Vue2很多项目在用,但是官方已经宣布不再维护Vue2,所以新项目肯定首选Vue3来进行开发,组合式API开发起来比选项式API方便多了,而且Vue3的响应式实现也更...
- 基于 Vue3 Element Plus 的中后台管理系统模板
-
PureAdmin是一个开源的前端中后台管理系统模板,基于Vue3、Element-Plus,支持移动端、国际化、多主题设置,支持前端静态路由、后端动态路由配置,旨在为开发人员提供一个易于使用、高...
- 重磅!滴滴开源全新跨端小程序框架,基于 Vue 3!
-
最近,滴滴出行开源了自主研发的全新轻量级跨端小程序框架——星河(Dimina),为开发者提供了“一次开发,多端运行”的高性能、低门槛解决方案。下面就来一览Dimina的魅力!什么是星河(Dim...
- 【推荐】一款基于 Vue + .NET 8 开源、免费、功能强大的快速开发框架
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍Vue.NetCore是一款集高效、灵活、易于扩展于一体的快速开发框架(基于Vue提供Vue2/Vue...
- 搭建Trae+Vue3的AI开发环境(vue ide 开发工具)
-
从2024年2025年,不断的有各种AI工具会在自媒体中火起来,号称各种效率王炸,而在AI是否会替代打工人的话题中,程序员又首当其冲。作为一个后端开发,这篇文章基于Trae工具,来创建和运行一个简单的...
- 一款基于 Vue + .NET 8 开源、免费、功能强大的快速开发框架
-
项目介绍Vue.NetCore是一款集高效、灵活、易于扩展于一体的快速开发框架(基于Vue提供Vue2/Vue3版本和.NET8前后端分离),适用于多种应用场景。通过前后端分离的设计、强大的...
- 盘点一下这些年PHP在桌面应用方面的解决方案
-
今天作者给大家盘点一下近些年PHP在实现桌面客户端方面的项目。PHP-GTKPHP-GTK是2001年3月创立,是PHP的一个扩展,实现了与GTK+的绑定,提供面向对象的接口,极大地简化了客户端跨平台...
- PHP+Uniapp校园圈子系统校园论坛小程序开发:踩坑与优化经验分享
-
一、系统架构与技术选型1.架构设计采用前后端分离架构,前端使用Uniapp实现跨端开发(支持微信小程序、H5、App),后端基于PHP(推荐ThinkPHP或Laravel框架)提供RESTful...
- 智能匹配+安全护航:PHP代练系统护航小程序如何提升用户信任?
-
在代练行业中,用户信任是平台发展的核心要素。基于PHP后端与uni-app跨端框架的代练系统,通过智能匹配与安全护航两大核心策略,能够有效提升用户信任,构建健康可持续的代练生态。以下从技术实现与用户体...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- beego框架 (52)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)