AyugeSpiderTools 教程

在本教程中,我们假设您的系统上已经安装了 ayugespidertools

我们要抓取 blog.csdn.net,这是一个知识问答社区的网站。

本教程将引导您完成这些任务:

  • 创建一个新的 Scrapy 项目

  • 编写爬虫来抓取站点并提取数据

  • 使用命令行导出抓取的数据

  • 更改蜘蛛以递归地跟踪链接

  • 使用蜘蛛参数

创建项目

在开始抓取之前,您必须设置一个新的 ayugespidertools 项目。输入您要存储代码的目录并运行:

ayugespidertools startproject DemoSpider

这将创建一个 DemoSpider 包含以下内容的目录:

DemoSpider/
|-- DemoSpider							# project's Python module, you'll import your code from here
|   |-- __init__.py
|   |-- items.py						# project items definition file, 数据库表枚举信息示例也迁移至此
|   |-- logs							# 日志管理文件夹,可以自定义规则
|   |   |-- DemoSpider.log					# scrapy 输出日志,文件名称为项目名
|   |   |-- error.log						# loguru 日志 error 规则输出文件
|   |-- middlewares.py						# project middlewares definition file
|   |-- pipelines.py						# project pipelines definition file
|   |-- run.py							# scrapy 运行文件
|   |-- run.sh							# 项目运行 shell,运行以上的 run.py,win 平台不会生成此文件
|   |-- settings.py						# project settings definition file
|   |-- spiders							# a directory where you'll later put your spiders
|   |   |-- __init__.py
|   `-- VIT
|       `-- .conf        				        # 配置文件,用于修改 Mysql, MongoDB 等配置
|-- .gitignore							# git ignore 文件
|-- pyproject.toml						# 项目配置
|-- README.md							# 说明文档
|-- requirements.txt						# 依赖文件
`-- scrapy.cfg                                                  # deploy configuration file

我们的第一个 Spider

这是我们第一个 Spider 的代码。demo_one.py将其保存在项目目录下命名的文件 DemoSpider/spiders中:

from ayugespidertools.common.utils import ToolsForAyu
from ayugespidertools.items import DataItem, MongoDataItem, MysqlDataItem
from ayugespidertools.spiders import AyuSpider
from scrapy.http import Request

from DemoSpider.items import TableEnum

"""
########################################################################################################################
# collection_website: CSDN - 专业开发者社区
# collection_content: 热榜文章排名 Demo 采集示例 - 同时存入 Mysql 和 MongoDB 的场景
# create_time: 2022-08-22
# explain: 根据本项目中的 demo_one 脚本修改而得
# demand_code_prefix = ""
########################################################################################################################
"""


class DemoEightSpider(AyuSpider):
    name = "demo_eight"
    allowed_domains = ["blog.csdn.net"]
    start_urls = ["https://blog.csdn.net/"]

    # 数据库表的枚举信息
    custom_table_enum = TableEnum
    # 初始化配置的类型
    settings_type = "debug"
    custom_settings = {
        # 是否开启记录项目相关运行统计信息
        "RECORD_LOG_TO_MYSQL": False,
        # 数据表的前缀名称,用于标记属于哪个项目,也可以不用添加
        "MYSQL_TABLE_PREFIX": "demo8_",
        # 数据表的前缀名称,用于标记属于哪个项目(也可不配置此参数,按需配置)
        "MONGODB_COLLECTION_PREFIX": "demo8_",
        "ITEM_PIPELINES": {
            # 激活此项则数据会存储至 Mysql
            "ayugespidertools.pipelines.AyuFtyMysqlPipeline": 300,
            # 激活此项则数据会存储至 MongoDB
            "ayugespidertools.pipelines.AyuFtyMongoPipeline": 301,
        },
        "DOWNLOADER_MIDDLEWARES": {
            # 随机请求头
            "ayugespidertools.middlewares.RandomRequestUaMiddleware": 400,
        },
    }

    # 打开 mysql 引擎开关,用于数据入库前更新逻辑判断
    mysql_engine_enabled = True

    def start_requests(self):
        """
        get 请求首页,获取项目列表数据
        """
        yield Request(
            url="https://blog.csdn.net/phoenix/web/blog/hot-rank?page=0&pageSize=25&type=",
            callback=self.parse_first,
            headers={
                "referer": "https://blog.csdn.net/rank/list",
                "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
            },
            dont_filter=True,
        )

    def parse_first(self, response):
        data_list = ToolsForAyu.extract_with_json(
            json_data=response.json(), query="data"
        )
        for curr_data in data_list:
            article_detail_url = ToolsForAyu.extract_with_json(
                json_data=curr_data, query="articleDetailUrl"
            )

            article_title = ToolsForAyu.extract_with_json(
                json_data=curr_data, query="articleTitle"
            )

            comment_count = ToolsForAyu.extract_with_json(
                json_data=curr_data, query="commentCount"
            )

            favor_count = ToolsForAyu.extract_with_json(
                json_data=curr_data, query="favorCount"
            )

            nick_name = ToolsForAyu.extract_with_json(
                json_data=curr_data, query="nickName"
            )

            article_info = {
                "article_detail_url": DataItem(article_detail_url, "文章详情链接"),
                "article_title": DataItem(article_title, "文章标题"),
                "comment_count": DataItem(comment_count, "文章评论数量"),
                "favor_count": DataItem(favor_count, "文章赞成数量"),
                "nick_name": DataItem(nick_name, "文章作者昵称"),
            }

            ArticleMysqlInfoItem = MysqlDataItem(
                alldata=article_info,
                table=TableEnum.article_list_table.value["value"],
            )
            yield ArticleMysqlInfoItem

            ArticleInfoMongoItem = MongoDataItem(
                # alldata 用于存储 mongo 的 Document 文档所需要的字段映射
                alldata=article_info,
                # table 为 mongo 的存储 Collection 集合的名称
                table=TableEnum.article_list_table.value["value"],
                # mongo_update_rule 为查询数据是否存在的规则
                mongo_update_rule={"article_detail_url": article_detail_url},
            )
            yield ArticleInfoMongoItem

如您所见,我们的 Spider 子类化AyugeSpider.AyuSpider 并定义了一些属性和方法:

  • name: 标识蜘蛛。在一个项目中必须是唯一的,即不能为不同的Spiders设置相同的名字。

  • start_requests(): 必须返回一个可迭代的请求(你可以返回一个请求列表或编写一个生成器函数),蜘蛛将从中开始爬行。后续请求将从这些初始请求中依次生成。

  • parse_first():将被调用以处理为每个请求下载的响应的方法。response 参数是 TextResponse 的一个实例,它保存页面内容,并有进一步的有用方法来处理它。该 parse_first() 方法通常解析响应,将抓取的数据提取为字典,并找到要遵循的新 URL 并从中创建新请求 ( Request)。

另外,一些其它注意事项:

  • 示例中的一些配置和一些功能并不是每个项目中都必须要编写和配置的,只是用于展示一些功能

  • 据上条可知,可以写出很简洁的代码,删除你认为的无关配置和方法并将其配置成你自己的模板就更容易适配更多人的使用场景。

如何运行我们的蜘蛛

要让我们的蜘蛛工作,请转到项目的顶级目录并运行:

# 本身就是 scrapy 的项目,所以可以使用 scrapy 可以执行的任何形式即可
scrapy crawl demo_one

# 或者执行项目根目录下的 run.py(需要编辑自己需要执行的脚本)
python run.py

# 或者执行项目根目录下的 run.sh,其实它也是通过调用 run.py 来执行的。只不过 shell 文件中包含了虚拟环境的 activate 了而已
sh run.sh