嗨,Scrapy 捋一遍

很久没有使用scrapy做爬虫了,突然写有点手生,所以捋一捋知识点,做一个博客,记录一下。

Scrapy 框架介绍

Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架。

相较于其他框架,scrapy的优势在于:

1、Scrapy 使用异步处理方式,能够同时处理多个请求,从而提高程序执行效率。

2、Scrapy 支持多种数据格式的解析和处理,包括HTML、XML、JSON等。

3、Scrapy 提供了一系列插件和组件,允许用户根据需要进行定制和扩展。

4、由于其异步处理和多线程的特性,Scrapy 特别适合于大规模网页抓取项目。

框架结构

Scrapy Engine:用来处理整个系统的数据流处理、触发事务,是整个框架的核心。 调度器Scheduler:用来接受引擎发过来的请求并加入队列中,并在引擎再次请求的时候提供给引擎。 管道item pipeline:负责处理由蜘蛛从网页中抽取的项目,它的主要任务是清洗、验证和存储数据。 爬虫器(爬虫组件) Spiders:其内定义了爬取的逻辑和网页的解析规则,它主要负责解析响应并生成提取结果和新的请求。 下载器 Downloader:用于下载网页内容,并将网页内容返回给Spiders爬虫器。 Downloader Middlewares(下载器中间件):位于引擎和下载器之间的钩子框架,主要是处理引擎与下载器之间的请求及响应。

请求流程

  1. 发起请求:首先,Spiders(爬虫)会提供需要抓取的网页的初始URL,然后将这些URL发送给Scrapy Engine(引擎)。
  2. 调度请求:Scrapy Engine将请求发送给Scheduler(调度器),Scheduler会对这些请求进行排序并放入队列中等待执行。
  3. 下载网页:当Scheduler调度好执行顺序后,Scrapy Engine会将请求发送给Downloader(下载器),Downloader会向互联网发送请求并接收下载的响应(response)。
  4. 处理响应:Downloader将接收到的响应返回给Scrapy Engine,Scrapy Engine再将响应发送给Spiders。Spiders会对响应进行解析,提取出需要的数据,并生成新的请求(如链接等)。
  5. 处理数据:提取到的数据会经过Scrapy Engine,然后交给Item Pipelines进行处理。Item Pipelines可以对数据进行清洗、过滤、存储等操作。
  6. 循环执行:如果在解析响应的过程中生成了新的请求,那么这些请求会重新经过Scrapy Engine发送给Scheduler进行调度,如此循环执行,直到没有更多的请求需要处理,程序才会停止。

Scrapy 初始

框架安装

创建沙箱
bash 复制代码
# 切入沙箱目录
cd F:\2024\Project\SpiderProject
# 创建沙箱
D:\Python37\python.exe -m venv venv
# 激活沙箱
.\venv\Scripts\activate.bat
安装框架
csharp 复制代码
pip install scrapy
​
Installing collected packages: twisted-iocpsupport, PyDispatcher, incremental, constantly, zope.interface, zipp, w3lib, urllib3, typing-extensions, six, queuelib, pycparser, pyasn1, protego, packaging, lxml, jmespath, itemadapter, idna, filelock, cssselect, charset-normalizer, certifi, requests, pyasn1-modules, parsel, importlib-metadata, hyperlink, cffi, requests-file, itemloaders, cryptography, attrs, tldextract, service-identity, pyOpenSSL, automat, Twisted, scrapy
Successfully installed PyDispatcher-2.0.7 Twisted-23.8.0 attrs-23.2.0 automat-22.10.0 certifi-2024.2.2 cffi-1.15.1 charset-normalizer-3.3.2 constantly-15.1.0 cryptography-42.0.2 cssselect-1.2.0 filelock-3.12.2 hyperlink-21.0.0 idna-3.6 importlib-metadata-6.7.0 incremental-22.10.0 itemadapter-0.8.0 itemloaders-1.1.0 jmespath-1.0.1 lxml-5.1.0 packaging-23.2 parsel-1.8.1 protego-0.3.0 pyOpenSSL-24.0.0 pyasn1-0.5.1 pyasn1-modules-0.3.0 pycparser-2.21 queuelib-1.6.2 requests-2.31.0 requests-file-2.0.0 scrapy-2.9.0 service-identity-21.1.0 six-1.16.0 tldextract-4.0.0 twisted-iocpsupport-1.0.4 typing-extensions-4.7.1 urllib3-2.0.7 w3lib-2.1.2 zipp-3.15.0 zope.interface-6.1
Scrapy 命令行
命令 描述
bench 运行快速基准测试
fetch 使用Scrapy下载器获取URL
genspider 使用预定义模板生成新的spider
runspider 运行独立的spider(不创建项目)
settings 获取Scrapy设置值
shell 交互式抓取控制台(调试,测试使用)
startproject 创建新项目
version 返回爬虫的版本
view 下载连接文件,并在浏览器打开这个文件

创建项目

.\venv\Scripts\scrapy.exe startproject baiduSpider
命令 描述
check 检测爬虫
crawl 启动爬虫
edit 编辑爬虫
list 列出可以使用的爬虫
parse 解析URL(使用其spider)并打印结果
创建独立爬虫应用
bash 复制代码
cd F:\2024\Project\SpiderProject\baiduSpider
..\venv\Scripts\scrapy.exe genspider tieba tiebaSpider
项目结构

baiduSpider # 项目外壳目录

baiduSpider # 项目目录

spiders # 具体爬虫目录

init.py # 包初始化文件

tieba.py # 爬虫具体文件

init.py # 包初始化文件

item.py # 爬取数据的结构

middlewares.py # 爬虫中间件文件

pipelines.py # 爬虫数据传输文件

settings.py # 爬虫配置文件

scrapy.cfg # scrapy框架配置文件

一次基本的爬取

python 复制代码
import scrapy
from baiduSpider.items import TiebaspiderItem
​
class TiebaSpider(scrapy.Spider):
    name = "tieba"
    allowed_domains = ["tiebaSpider"]
    start_urls = ["https://tieba.baidu.com/index.html"]
​
    def parse(self, response):
        for iter in response.xpath("//div[@class='title-tag-wraper']/a"):
            ba_name = iter.attrib.get("title")
            print(ba_name)

Scrapy MiddleWare

在Scrapy中,Middleware(中间件)是一个处理请求和响应的组件,它在Scrapy引擎和下载器之间提供了一个钩子(hook),允许你对请求和响应进行预处理和后处理。Middleware可以用于执行各种任务,如设置请求头、重试失败的请求、记录日志、跟踪请求和响应等。要创建一个Middleware,你需要定义一个类并实现Scrapy提供的特定方法。这些方法会在请求和响应流经Scrapy时触发。以下是一个简单的Scrapy Middleware示例,它会在每个请求发出之前添加一个自定义的请求头:

ruby 复制代码
class CustomMiddleware:
​
    def process_request(self, request, spider):
        *# 添加一个自定义的请求头*
        request.headers.setdefault('X-Custom-Header', 'CustomValue')
​
    def process_response(self, request, response, spider):
        *# 你可以在这里对响应进行处理,比如检查状态码、修改内容等*
        return response
​
    def process_exception(self, request, exception, spider):
        *# 当请求抛出异常时,这个方法会被调用*
        *# 你可以在这里记录日志、重试请求等*
        pass

要使用这个Middleware,你需要在你的settings.py文件中添加或修改DOWNLOADER_MIDDLEWARES设置:

ini 复制代码
pythonDOWNLOADER_MIDDLEWARES = {    'myproject.middlewares.CustomMiddleware': 543,    # 其他中间件...}

确保将'myproject.middlewares.CustomMiddleware'替换为你Middleware的正确路径。数字543表示Middleware的优先级,数字越小优先级越高。

Scrapy内置了许多有用的Middleware,例如重试失败的请求、重定向、cookies和代理等。你可以通过修改settings.py文件中的DOWNLOADER_MIDDLEWARES和SPIDER_MIDDLEWARES来启用或禁用这些Middleware,或者添加你自己的Middleware。

Middleware在处理请求和响应时,可以返回None、Request对象或Response对象。返回None意味着请求被忽略,不会进一步处理。返回Request对象意味着使用新的请求替换原来的请求。返回Response对象意味着使用新的响应替换原来的响应。

Scrapy Pipline

在Scrapy中,Pipeline是负责处理由Spider爬取并返回的item的组件。Pipeline组件接收item,并对其进行一些后续处理,比如清理、验证和持久化数据。你可以编写自己的Pipeline来执行任何你需要的处理逻辑。

下面是一个简单的Scrapy Pipeline示例,它展示了如何将爬取的数据保存到CSV文件中:

python 复制代码
import csv
​
class CsvWriterPipeline:
    def open_spider(self, spider):
        self.file = open('items.csv', 'w', newline='', encoding='utf-8')
        self.writer = csv.writer(self.file)
        self.writer.writerow(['Field1', 'Field2', 'Field3'])  # 写入CSV的表头
​
    def close_spider(self, spider):
        self.file.close()
​
    def process_item(self, item, spider):
        self.writer.writerow([item['field1'], item['field2'], item['field3']])  # 写入item的数据
        return item

要使用这个Pipeline,你需要在你的settings.py文件中启用它:

ini 复制代码
ITEM_PIPELINES = {
    'myproject.pipelines.CsvWriterPipeline': 300,
}

这里的数字300表示Pipeline的优先级。数字越小,优先级越高。如果有多个Pipeline,Scrapy会按照优先级从高到低的顺序执行它们。

process_item方法是Pipeline中最关键的方法。每个item都会通过这个方法进行处理。在这个方法中,你可以对item进行任何你需要的处理,比如数据清洗、验证、转换格式等。处理完成后,你可以选择返回这个item(继续传递给下一个Pipeline组件)或者抛出一个DropItem异常(停止后续的处理并丢弃这个item)。

open_spider和close_spider方法分别在爬虫开始时和结束时调用,你可以在这些方法中执行一些初始化和清理工作,比如打开和关闭文件。

请注意,在process_item方法中,你需要确保写入的CSV文件是线程安全的,因为Scrapy默认使用多线程来处理item。你可以使用csv.writer的线程安全版本,或者使用文件锁等机制来确保并发写入时的数据一致性。

最后,确保将'myproject.pipelines.CsvWriterPipeline'替换为你自己的Pipeline类的正确路径。

Scrapy 完整流程

spider.py

ini 复制代码
import scrapy
from baiduSpider.items import TiebaspiderItem
​
class TiebaSpider(scrapy.Spider):
    name = "tieba"
    allowed_domains = ["tiebaSpider"]
    start_urls = ["https://tieba.baidu.com/index.html"]
​
    def parse(self, response):
        for iter in response.xpath("//div[@class='title-tag-wraper']/a"):
            ba_name = iter.attrib.get("title")
            tb_item = TiebaspiderItem()
            tb_item["ba_name"] = ba_name
            yield tb_item

item.py

python 复制代码
import scrapy
​
​
class BaiduspiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass
​
class TiebaspiderItem(scrapy.Item):
    ba_name = scrapy.Field()

pipline.py

python 复制代码
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
​
​
# useful for handling different item types with a single interface
import csv
​
class BaiduspiderPipeline:
    def process_item(self, item, spider):
        return item
​
class TiebaSpiderCSVPipeline:
    def __init__(self):
        self.file = "open.csv"
​
    def open_spider(self, spider):
        self.file = open('items.csv', 'w', newline='', encoding='utf-8')
        self.writer = csv.writer(self.file)
        self.writer.writerow(['论坛标题'])  # 根据需要定义列名
​
    def process_item(self, item, spider):
        title = item["ba_name"]
        self.writer.writerow([title])
        return item
​
    def close_spider(self, spider):
        self.file.close()
​

案例很简单,后续还想基于scarpy+redis进行分布式数据采集,还请给各位大佬多多指点。

相关推荐
一个闪现必杀技8 分钟前
Python入门--函数
开发语言·python·青少年编程·pycharm
小鹿( ﹡ˆoˆ﹡ )28 分钟前
探索IP协议的神秘面纱:Python中的网络通信
python·tcp/ip·php
卷心菜小温44 分钟前
【BUG】P-tuningv2微调ChatGLM2-6B时所踩的坑
python·深度学习·语言模型·nlp·bug
陈苏同学1 小时前
4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1
linux·服务器·ide·人工智能·python·深度学习·pycharm
唐家小妹1 小时前
介绍一款开源的 Modern GUI PySide6 / PyQt6的使用
python·pyqt
羊小猪~~2 小时前
深度学习项目----用LSTM模型预测股价(包含LSTM网络简介,代码数据均可下载)
pytorch·python·rnn·深度学习·机器学习·数据分析·lstm
Marst Code2 小时前
(Django)初步使用
后端·python·django
985小水博一枚呀2 小时前
【对于Python爬虫的理解】数据挖掘、信息聚合、价格监控、新闻爬取等,附代码。
爬虫·python·深度学习·数据挖掘
立秋67892 小时前
Python的defaultdict详解
服务器·windows·python
萧鼎3 小时前
Python第三方库选择与使用陷阱避免
开发语言·python