爬取、下载哔哩哔哩、小红书等网站数据、视频, 持续更新中...
Warning:
本项目仅供学习交流使用, 请勿用于商业及非法用途, 由此引起的一切后果与作者无关
https://github.com/iiicebearrr/spiders-for-all/assets/110714291/32e098d3-c85e-44c9-b54c-4820365b0235
根据用户id爬取b站用户主页投稿视频
python -m spiders_for_all bilibili download-by-author -m 用户id -s 保存目录
根据note_id批量爬取小红书笔记内容
python -m spiders_for_all xhs download-by-id -i note_id1,note_id2,note_id3 -s 保存目录
更多用法见Documentation部份
pip install spiders-for-all # python 版本 >= 3.12
点击进入对应平台的使用文档
如果你想自定义爬虫, 可以参考以下指引
首先需要了解一下项目爬虫的基本结构, 参考下图:
spiders_for_all/spiders
目录下存放各个平台的爬虫, 每个爬虫都是一个类, 继承自spiders_for_all.core.spider.BaseSpider
类, 并实现BaseSpider
类的get_items_from_response
方法
继承自BaseSpider
的爬虫, 会按照以下流程爬取目标网站数据
self.__init__
: 初始化爬虫cls.db_action_on_init
:
spiders_for_all.core.spider.DbActionOnInit.CREATE_IF_NOT_EXISTS
: 如果表不存在则创建spiders_for_all.core.spider.DbActionOnInit.DROP_AND_CREATE
: 直接删除并创建表client
是一个spiders_for_all.core.client.HttpClient
对象, 封装了失败重试、日志、以及生成模拟请求头user-agent
的功能self.run
: 运行爬虫self.before
: 运行爬虫前执行的代码, 默认会打印一条日志self.get_items
: 从目标网站获取数据
self.request_items
: 向self.api
发送请求, 获取返回。会调用self.get_request_args
获取额外的请求参数比如params
, data
等等self.validate_response
: 验证返回体结构, 如果定义了self.response_model
, 会调用self.response_model
基于pydantic
对返回体进行验证。注意这里的验证是业务验证, 不是HTTP状态的验证, self.client
会自动验证HTTP状态。 如果没有定义self.response_model
, 则不会进行验证,直接返回原始的requests.Response
对象self.get_items_from_response
: 从验证成功的返回体中取出对应的items, 返回items的数据类型完全取决于cls.item_model
, 具体可以参考几个爬虫的实现self.request_items()
, self.validate_response
, self.get_items_from_response
均被封装在一个retry
的wrapper内,这也就意味着如果出现: HTTP状态码非200
, 业务返回体异常, 比如哔哩哔哩的-352业务码
, 获取items失败,比如网页没有返回正常的数据
这些情况, 均会触发自动重试self.save_items
: 将爬取的数据保存到数据库self.after
: 运行爬虫后执行的代码, 默认会打印一条日志除此之外, 需要额外定义一些类属性, 示例如下
import typing as t
import logging
import requests
from sqlalchemy import orm
from pydantic import BaseModel
from spiders_for_all.core.response import Response
from spiders_for_all.core.spider import BaseSpider, DbActionOnInit, DbActionOnSave
from spiders_for_all.database.session import SessionManager
from spiders_for_all.utils.logger import default_logger
class MySpider(BaseSpider):
api: str # 目标API, 必须
name: str # 爬虫名称, 必须
alias: str # 爬虫别名, 必须
platform: str # 爬虫所属平台, 必须
description: str = "" # 爬虫描述, 可选
database_model: t.Type[orm.DeclarativeBase] # 数据库表模型, 必须
item_model: t.Type[BaseModel] # 爬取的数据模型, 必须
response_model: t.Type[Response] | None = None # 返回体模型, 可选
logger: logging.Logger = default_logger # 日志对象, 可选
session_manager: SessionManager # 数据库连接管理器, 必须
insert_batch_size: int = 100 # 批量插入数据库时的批量大小, 可选
db_action_on_init: DbActionOnInit = DbActionOnInit.CREATE_IF_NOT_EXIST # 初始化数据库表时的行为, 可选
db_action_on_save: DbActionOnSave = DbActionOnSave.DELETE_AND_CREATE # 保存数据时的行为, 可选
def get_items_from_response(self, response: requests.Response | Response) -> t.Iterable[BaseModel]:
# 从返回体中取出items, 必须
pass
ON CONFLICT DO UPDATE
语法, 如果遇到该问题请尝试升级sqlite版本 grep ERROR logs/bilibili.log
可以查看有哪些视频下载失败, 然后收集bvid重新下载即可。未来会考虑处理这种情况dm_img_inter
参数, 目前作者还没有时间实现该参数的生成算法, 所以该接口暂时无法使用, 但是如果你实现了该参数的生成算法, 可以通过修改spiders_for_all.spiders.bilibili.AuthorSpider
中的get_request_args
方法来继续使用该接口