百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

爬虫修炼手册,Python爬虫学习入门Scrapy

myzbx 2025-03-20 17:00 16 浏览

爬虫就如同江湖中的神秘侠客,应运而生,成为了我们获取数据的得力助手。爬虫,正式名称是网络爬虫(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:在这个文件中,定义了爬虫要抓取的数据结构,也就是ItemItem类似于一个容器,用于存储从网页中提取的数据。比如我们要抓取电商网站上的商品信息,就可以在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_idusernamegenderfollowing_countfollower_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_urimongo_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_URIMONGO_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.pyspiderspipelines.pymiddlewares.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##如何自学Python#

#python自学##Python编程从入门到实践#

#Python基础#

相关推荐

Django零基础速成指南:快速打造带用户系统的博客平台

#python##服务器##API##编程##学习#不是所有教程都值得你花时间!这篇实战指南将用5分钟带你解锁Django核心技能,手把手教你从零搭建一个具备用户注册登录、文章管理功能的完整...

iOS 17.0 Bootstrap 1.2.9 半越狱来啦!更新两点

这款Bootstrap半越狱工具终于更新,离上一次更新已相隔很久,现在推出1.2.9版本,主要为内置两点功能进行更新,也是提升半越狱的稳定性。如果你正在使用这款半越狱工具的,建议你更新。注意!...

iOS 16.x Bootstrap 1.2.3 发布,支持运行清理工具

本文主要讲Bootstrap半越狱工具更新相关内容。如果你是iOS16.0至16.6.1和17.0系统的,想体验半越狱的果粉,请继续往下看。--知识点科普--Bootstrap...

SpringBoot整合工作流引擎Acticiti系统,适用于ERP、OA系统

今日推荐:SpringBoot整合工作流引擎Acticiti的源码推荐理由:1、SpringBoot整合工作流引擎Acticiti系统2、实现了三级权限结构3、持久层使用了mybatis框架4、流程包...

SpringCloud自定义Bootstrap配置指南

在SpringCloud中自定义Bootstrap配置需要以下步骤,以确保在应用启动的早期阶段加载自定义配置:1.添加依赖(针对新版本SpringCloud)从SpringCloud2020...

Python使用Dash开发网页应用(三)(python网页开发教程)

PlotlyDash开发Web应用示例一个好的网页设计通常都需要编写css甚至js来定制前端内容,例如非常流行的bootstrap框架。我们既然想使用Dash来搭建web应用,很大的一个原因是不熟悉...

Oxygen XML Editor 27.1 中的新功能

OxygenXMLEditor27.1版是面向内容作者、开发者、合作者和出版商的行业领先工具包的增量版本。在27.1版本中,AIPositronAssistant得到了增强,包括用于...

【LLM-多模态】Mini-Gemini:挖掘多模态视觉语言模型的潜力

一、结论写在前面论文提出了Mini-Gemini,一个精简而强大的多模态VLM框架。Mini-Gemini的本质在于通过战略性框架设计、丰富的数据质量和扩展的功能范围,发掘VLM的潜在能力。其核心是补...

谐云课堂 | 一文详解分布式改造理论与实战

01微服务与分布式什么是分布式?首先,我们对上图提到的部分关键词进行讲解。单体,是指一个进程完成全部的后端处理;水平拆分,是同一个后端多环境部署,他们都处理相同的内容,使用反向代理来均衡负载,这种也叫...

基于Abaqus的手动挡换挡机构可靠性仿真

手动挡,也称手动变速器,英文全称为Manualtransmission,简称MT,即用手拨动换挡操纵总成才能改变变速器内的齿轮啮合位置,改变传动比,从而达到变速的目的。家用轿车主要采用软轴连接的换挡...

【pytorch】目标检测:彻底搞懂YOLOv5详解

YOLOv5是GlennJocher等人研发,它是Ultralytics公司的开源项目。YOLOv5根据参数量分为了n、s、m、l、x五种类型,其参数量依次上升,当然了其效果也是越来越好。从2020...

超实用!50个非常实用的PS快捷键命令大全分享

今天,给大家介绍50个非常实用的快捷键命令大全,大家伙都是设计师,关于软件使用那是越快越好啊。一、常用的热键组合1、图层混合模式快捷键:正常(Shift+Option+N),正片叠底(Shif...

Pohtoshop中深藏不露的小技巧(科目一考试技巧记忆口诀看完必过)

邢帅教育ps教程为大家总结了一些Pohtoshop中深藏不露的小技巧,可以帮助到大家在设计时减少不必要的麻烦,提高工作效率哦~~~1.设置网格线保持像素完美不在1:1分辨率下也能保持像素完美,可以...

Ganglia监控安装总结(监控安装工作总结)

一、ganglia简介:Ganglia是一个跨平台可扩展的,高性能计算系统下的分布式监控系统,如集群和网格。它是基于分层设计,它使用广泛的技术,如XML数据代表,便携数据传输,RRDtool用于数据...

谁说Adobe XD做不出好看的设计?那是你没搞懂这些功能

AdobeXD的美化栏具有将设计视图美化的功能,它能使界面设计和原型设计更漂亮、更吸引眼球。美化栏的7个功能包括竖线布局设计、横线布局设计、重复网格、图形大小和位置设置、响应式调整大小、文字美化以及...