datasette-scraper
是一个 Datasette 插件,用于管理小型(约 10 万页)抓取和提取作业。
- 有主见但可扩展
- 一些有用的任务开箱即用,或者编写自己的 pluggy hook 来实现更多功能
- 深度依赖 SQLite
- 通过 Datasette 中公开的操作表来内省你的抓取
- 基于强大的库构建
- 以 Datasette 作为宿主
- selectolax 用于 HTML 解析
- httpx 用于 HTTP 请求
- pluggy 用于扩展性
- zstandard 用于高效压缩 HTTP 响应
不适用于对抗性抓取。想抓取屏蔽机器人的网站?你需要自己搞定。
在与 Datasette 相同的环境中安装此插件。
datasette install datasette-scraper
通过 metadata.json
配置 datasette-scraper
。你需要在每个数据库级别启用该插件。
要在 my-database
数据库中启用它,可以这样写
{
"databases": {
"my-database": {
"plugins": {
"datasette-scraper": {
}
}
}
}
}
下次启动 datasette 时,该插件将在指定的数据库中创建几个表。前往 dss_crawl
表来定义抓取。
提供了一个 10 分钟的端到端操作视频
datasette-scraper
需要一个数据库来跟踪其操作数据,还需要一个数据库来存储抓取的数据。它们可以是同一个数据库。
两个数据库都将设置为 WAL 模式。
操作数据库的 user_version
pragma 将用于跟踪模式版本。
datasette-scraper
处理抓取的核心簿记工作——跟踪待抓取的 URL、限制对来源的请求速率、将数据持久化到数据库中。它依赖插件来完成几乎所有有趣的工作。例如,获取实际页面、跟踪重定向、导航站点地图、提取数据。
该工具附带了用于常见用例的插件。一些用户可能希望编写自己的 after_fetch_url
或 extract_from_response
实现来进行自定义处理。
flowchart LR
direction TB
subgraph init
A(user starts crawl) --> B[get_seed_urls]
end
subgraph crawl [for each URL to crawl]
before_fetch_url --> fetch_cached_url --> fetch_url --> after_fetch_url
fetch_cached_url --> after_fetch_url
end
subgraph discover [for each URL crawled]
discover_urls --> canonicalize_url --> canonicalize_url
canonicalize_url --> x[queue URL to crawl]
extract_from_response
end
init --> crawl --> discover
大多数插件只会实现其中几个钩子。
conn
是一个读/写数据库的sqlite3.Connection
对象config
是抓取的配置
返回一个字符串列表,表示要抓取的种子 URL。
它们将被视为深度为 0,即种子。
request_headers
是一个字典,你可以修改它来控制请求中发送的内容。
返回
- truthy 值表示不应抓取此 URL(例如,达到最大抓取页数限制)
- falsy 值表示没有意见
注意
before_fetch_url
与canonicalize_url
你还可以使用
canonicalize_url
钩子在 URL 进入抓取队列之前拒绝它们。被
canonicalize_url
拒绝的 URL 将不会在dss_crawl_queue
和dss_crawl_queue_history
表中生成条目。使用哪个取决于你的偏好,通常情况下,如果你永远都不想要某个 URL,就在规范化时拒绝它。
获取之前缓存的 HTTP 响应。系统在调用此方法之前不会检查速率限制是否可用。
返回
None
,表示未处理- 一个响应对象,它是一个包含以下内容的字典
fetched_at
- 一个 ISO 8601 时间格式,如2022-12-26 01:23:45.00
headers
- 响应头,例如[['content-type', 'text/html']]
status_code
- 响应码,例如200
text
- 响应体
一旦任何插件返回了 truthy 值,其他插件的 fetch_url
钩子将不会被调用。
从活动服务器获取 HTTP 响应。系统在调用此方法之前会检查速率限制是否可用。
与 fetch_cached_url
具有相同的返回类型和行为。
对已抓取的 URL 进行处理。
返回一个待抓取的 URL 列表。
URL 可以是字符串,在这种情况下它们将被加入队列,深度为 depth + 1;也可以是包含 URL 和深度的元组。这对于分页索引页非常有用,你可以设定最大抓取深度为 2,但将所有索引页都视为深度 1。
返回
False
用于过滤 URL- 用于替代的待抓取 URL
None
或True
表示不做任何操作
待抓取的 URL 可以是字符串,也可以是包含字符串和深度的元组。
此钩子适用于
- 阻止我们永远不想要的 URL
- 规范化 URL,例如,省略查询参数
- 将抓取限制在同一来源
- 重置分页深度
返回一个表示待插入或待更新插入行的对象
列名末尾可以带符号
!
表示该列是主键的一部分;该值最多只能对应一行数据@
表示该列应该被索引;该值可以对应多行数据
带符号的列必须在创建表时已知。虽然你可以有多个带符号的列,但在同一个表中不能混用 !
和 @
符号。
任何缺失的表或列都将创建。列将具有 ANY
数据类型。除非列带有 !
符号,否则将允许空值。
你可以通过在你的对象中发出 __delete
键来指示应该删除某一行。
为了减少写事务并提高吞吐量,datasette-scraper
可能会批量提交你的更改到数据库。如果它确定数据库状态不会改变,它甚至可能完全省略 DELETE/INSERT 语句。
如果你想更精细地控制模式,请手动创建表。
这些钩子不影响抓取操作。它们提供元数据,帮助验证用户的配置并显示用于配置抓取的 UI。
返回一个 ConfigSchema
选项,该选项定义了如何配置此插件。
配置通过 JSON schema 完成。UI 通过 JSON Forms 完成。
请查看现有插件,了解如何使用此钩子。
模式是可选的;如果省略,你需要以带外方式配置插件。
返回 None
表示新抓取默认不应使用此插件。
否则,返回一个符合 config_schema()
中模式的合理默认值
要在本地设置此插件,首先检出代码。然后创建一个新的虚拟环境
cd datasette-scraper
python3 -m venv venv
source venv/bin/activate
现在安装依赖和测试依赖
pip install -e '.[test]'
运行测试
pytest