跳转到主要内容

Croquemort链接检查器

项目描述

# Croquemort

## 愿景

本项目旨在提供一个检查HTTP资源的方法:查找404错误、更新重定向等。

例如,对于一个存储外部资源列表(HTML、图像或文档)的网站,此产品允许所有者批量发送其URL,并在后台检索每个获取的URL的信息(目前是状态码和有用的头信息)。这样,他可以了解死链或过时资源,并据此采取行动。

该名称来自[法语](https://fr.wikipedia.org/wiki/Croque-mort)中[殡仪员](https://en.wikipedia.org/wiki/Funeral_director)的术语。


## 语言

开发语言是英语。所有注释和文档都应使用英语编写,这样我们就不会使用“法式英语”方法,并且我们可以与全世界的开发者分享我们的经验。


## 历史

我们于2015年5月开始为[data.gouv.fr](http://data.gouv.fr/)开发此项目。

我们从一开始就开源了它,因为我们希望在公开环境中设计事物,并让市民和黑客参与到我们的开发中来。


## 安装

我们使用以下技术:RabbitMQ 和 Redis。在安装和运行 Python 包之前,您必须安装和启动这些依赖项。

安装完成后,运行以下命令设置项目

```shell
$ python3 -m venv ~/.virtualenvs/croquemort
$ source ~/.virtualenvs/croquemort/bin/activate
$ pip3 install -r requirements/develop.pip
```

您现在可以开始了!


## 使用方法

首先,您必须运行 `http` 服务以接收传入的 HTTP 调用。您可以使用此命令运行它

```shell
$ nameko run croquemort.http
启动服务:http_server
已连接到 amqp://guest:**@127.0.0.1:5672//
```

然后在新的 shell 中启动 `crawler`,它将在后台抓取提交的 URL。

```shell
$ nameko run croquemort.crawler
启动服务:url_crawler
已连接到 amqp://guest:**@127.0.0.1:5672//
```

您可以选择使用建议的配置(并对其进行调整)以获取一些日志(默认为 `INFO` 级别)

```shell
$ nameko run --config config.yaml croquemort.crawler
```

您可以在配置文件中启用更多爬虫工作者(从默认的 10 到 50)
```yaml
max_workers: 50
```



### 浏览您的数据

任何时候,您都可以打开 `http://localhost:8000/` 并检查您 URL 集合的可用性,在精美的仪表板中可以按状态、内容类型、URL 方案、最后更新和/或域名进行筛选。如果您想编写脚本,还可以导出您当前查看的数据的 CSV 格式。


### 获取单个 URL

现在您可以使用您喜欢的 HTTP 客户端(我的客户端是 [httpie](https://github.com/jakubroztocil/httpie))向 `localhost:8000/check/one` 发送 POST 请求,将 URL 作为参数

```shell
$ http :8000/check/one url="https://www.data.gouv.fr/fr/"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 28
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:21:50 GMT

{
"url-hash": "u:fc6040c5"
}
```

此服务返回一个 URL 哈希,将用于检索与该 URL 相关的信息

```shell
$ http :8000/url/u:fc6040c5
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 335
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:22:57 GMT

{
"etag": "",
"checked-url": "https://www.data.gouv.fr/fr/",
"final-url": "https://www.data.gouv.fr/fr/",
"content-length": "",
"content-disposition": "",
"content-md5": "",
"content-location": "",
"expires": "",
"final-status-code": "200",
"updated": "2015-06-03T16:21:52.569974",
"last-modified": "",
"content-encoding": "gzip",
"content-type": "text/html; charset=utf-8"
}
```

您也可以使用作为 GET 参数传递的 URL(更不易出错)

```shell
$ http GET :8000/url url=https://www.data.gouv.fr/fr/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 335
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:23:35 GMT

{
"etag": "",
"checked-url": "https://www.data.gouv.fr/fr/",
"final-url": "https://www.data.gouv.fr/fr/",
"content-length": "",
"content-disposition": "",
"content-md5": "",
"content-location": "",
"expires": "",
"final-status-code": "200",
"updated": "2015-06-03T16:21:52.569974",
"last-modified": "",
"content-encoding": "gzip",
"content-type": "text/html; charset=utf-8"
}
```

两者返回相同数量的信息。


### 获取多个 URL

您还可以使用您的 HTTP 客户端向 `localhost:8000/check/many` 发送 POST 请求,将 URL 和组名作为参数

```shell
$ http :8000/check/many urls:='["https://www.data.gouv.fr/fr/","https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png"]' group="datagouvfr"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 30
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:24:00 GMT

{
"group-hash": "g:efcf3897"
}
```

这次,服务返回一个组哈希,将用于检索与该组相关的信息

```shell
$ http :8000/group/g:efcf3897
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 941
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:26:04 GMT

{
"u:179d104f": {
"content-encoding": "",
"content-disposition": "",
"group": "g:efcf3897",
"last-modified": "Tue, 31 Mar 2015 14:38:37 GMT",
"content-md5": "",
"checked-url": "https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png",
"final-url": "https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png",
"final-status-code": "200",
"expires": "",
"content-type": "image/png",
"content-length": "280919",
"updated": "2015-06-03T16:24:00.405636",
"etag": "\"551ab16d-44957\"",
"content-location": "
},
"name": "datagouvfr",
"u:fc6040c5": {
"content-disposition": "",
"content-encoding": "gzip",
"group": "g:efcf3897",
"last-modified": "",
"content-md5": "",
"content-location": "",
"content-length": "",
"expires": "",
"content-type": "text/html; charset=utf-8",
"final-status-code": "200",
"updated": "2015-06-03T16:24:02.398105",
"etag": "",
"checked-url": "https://www.data.gouv.fr/fr/"
"final-url": "https://www.data.gouv.fr/fr/"
}
}
```

或者您可以使用作为GET参数传递的组名(更不易出错)

```shell
$ http GET :8000/group/ group=datagouvfr
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 335
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:23:35 GMT

{
"etag": "",
"checked-url": "https://www.data.gouv.fr/fr/",
"final-url": "https://www.data.gouv.fr/fr/",
"content-length": "",
"content-disposition": "",
"content-md5": "",
"content-location": "",
"expires": "",
"final-status-code": "200",
"updated": "2015-06-03T16:21:52.569974",
"last-modified": "",
"content-encoding": "gzip",
"content-type": "text/html; charset=utf-8"
}
```

两者返回相同数量的信息。


### 重定向处理

在抓取一个或多个URL时,croquemort 对HTTP重定向提供了基本支持。首先,croquemort 会遵循重定向到最后目的地(`requests`库的`allow_redirects`选项)。此外,croquemort 还会存储一些关于重定向的信息:第一个重定向代码和最终URL。遇到重定向时,JSON响应如下(注意`redirect-url`和`redirect-status-code`)

```json
{
"checked-url": "https://goo.gl/ovZB",
"final-url": "http://news.ycombinator.com",
"final-status-code": "200",
"redirect-url": "https://goo.gl/ovZB",
"redirect-status-code": "301",
"etag": "",
"content-length": "",
"content-disposition": "",
"content-md5": "",
"content-location": "",
"expires": "",
"updated": "2015-06-03T16:21:52.569974",
"last-modified": "",
"content-encoding": "gzip",
"content-type": "text/html; charset=utf-8"
}
```


### 过滤结果

您可以使用带有`filter_`前缀的头部(或状态)来过滤给定组返回的结果

```shell
$ http GET :8000/group/g:efcf3897 filter_content-type="image/png"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 539
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:27:07 GMT

{
"u:179d104f": {
"content-encoding": "",
"content-disposition": "",
"group": "g:efcf3897",
"last-modified": "Tue, 31 Mar 2015 14:38:37 GMT",
"content-md5": "",
"checked-url": "https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png",
"final-url": "https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png",
"final-status-code": "200",
"expires": "",
"content-type": "image/png",
"content-length": "280919",
"updated": "2015-06-03T16:24:00.405636",
"etag": "\"551ab16d-44957\"",
"content-location": "
},
"name": "datagouvfr"
}
```

您可以使用带有`exclude_`前缀的头部(或状态)来排除给定组返回的结果

```shell
$ http GET :8000/group/g:efcf3897 exclude_content-length=""
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 539
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:27:58 GMT

{
"u:179d104f": {
"content-encoding": "",
"content-disposition": "",
"group": "g:efcf3897",
"last-modified": "Tue, 31 Mar 2015 14:38:37 GMT",
"content-md5": "",
"checked-url": "https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png",
"final-url": "https://www.data.gouv.fr/s/images/2015-03-31/d2eb53b14c5f4e6690e150ea7be40a88/cover-datafrance-retina.png",
"final-status-code": "200",
"expires": "",
"content-type": "image/png",
"content-length": "280919",
"updated": "2015-06-03T16:24:00.405636",
"etag": "\"551ab16d-44957\"",
"content-location": "
},
"name": "datagouvfr"
}
```

请注意,在这两种情况下,`http`和`crawler`服务都会返回有趣的日志信息以供调试(如果您在`run`命令中传递了`--config config.yaml`选项)。


### 计算多个URL

您可以使用RPC代理以编程方式注册新的URL和组。`example_csv.py`文件中包含一个示例,该示例从CSV文件(每行一个URL)计算URL。

```shell
$ PYTHONPATH=. python tests/example_csv.py --csvfile path/to/your/file.csv --group groupname
组哈希:g:2752262332
```

脚本返回一个组哈希,您可以通过上述文档中所述的HTTP接口使用它。


### 频率

您可能希望定期在后台检查现有的URL组。在这种情况下,启动`timer`服务

```shell
$ nameko run croquemort.timer
启动服务:timer
已连接到 amqp://guest:**@127.0.0.1:5672//
```

现在,当您对`/check/many`进行`POST`操作或通过shell启动命令时,您现在可以指定`frequency`参数

```shell
$ PYTHONPATH=. python example_csv.py --csvfile path/to/your/file.csv --group groupname --frequency hourly
组哈希:g:2752262332
```

有三种可能性:“hourly”,“daily”和“monthly”。如果您不指定任何内容,您将不得不手动刷新URL检查。`timer`服务将检查与相关频率关联的组并相应地刷新相关的URL。


### Webhook

您不必轮询结果端点以获取一个或多个URL检查的结果,而是可以要求Croquemort在检查完成时调用webhook。

```shell
$ nameko run croquemort.webhook
启动服务:webhook_dispatcher
已连接到 amqp://guest:**@127.0.0.1:5672//
```

现在,当您对`/check/one`或`/check/many`进行`POST`操作时,您现在可以指定`callback_url`参数。

```shell
$ http :8000/check/one url="https://www.data.gouv.fr/fr/" callback_url="http://example.org/cb"
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 28
Content-Type: text/plain; charset=utf-8
Date: Wed, 03 Jun 2015 14:21:50 GMT

{
"url-hash": "u:fc6040c5"
}
```

当检查完成时,应向`http://example.org/cb`发出一个`POST`请求,包含检查的元数据。webhook服务期望一个成功的(例如,200)HTTP状态码。如果不是,它将重试(默认情况下)5次,首先等待10秒再重试,然后每次尝试增加延迟因子2。您可以通过设置变量`WEBHOOK_NB_RETRY`、`WEBHOOK_DELAY_INTERVAL`和`WEBHOOK_BACKOFF_FACTOR`来自定义这些值。

```json
{
"data": {
"checked-url": "http://yahoo.fr",
"final-url": "http://yahoo.fr",
"group": "g:a80c20d4",
"frequency": "hourly",
"final-status-code": "200",
"updated": "2017-07-10T12:50:20.219819",
"etag": "",
"expires": "-1",
"last-modified": "",
"charset": "utf-8",
"content-type": "text/html",
"content-length": "",
"content-disposition": "",
"content-md5": "",
"content-encoding": "gzip",
"content-location": "
}
}
```


### 迁移

您可能需要随着时间的推移使用`migrations`服务迁移一些数据

```shell
$ nameko run croquemort.migrations
启动服务:migrations
已连接到 amqp://guest:**@127.0.0.1:5672//
```

现在可以运行nameko shell

```shell
$ nameko shell
>>> n.rpc.migrations.split_content_types()
>>> n.rpc.migrations.delete_urls_for('www.data.gouv.fr')
>>> n.rpc.migrations.delete_urls_for('static.data.gouv.fr')
```

`split_content_types`迁移对于在使用报告集成之前使用Croquemort的情况很有用:我们通常会在`charset`前不分割整个字符串,这导致Content-types报告图碎片化。

`delete_urls_for`对于您想要删除与给定`domain`相关的所有URL很有用,您必须将`domain`作为参数传递:我们意外地检查了受我们控制的URL,因此我们决定清理以减少Redis数据库的大小并提高报告的相关性。

`migrate_from_1_to_2`(`migrate_urls_redirect`和`add_hash_prefixes`的元迁移)用于将您的数据库从croquemort `v1`迁移到`v2`。在`v2`中,API JSON模式对于检查结果有一些与`v1`的破坏性变化
- `url`变为`checked-url`
- `status`变为`final-status-code`

鼓励您将自定义迁移添加到服务中,并通过pull-requests与社区共享(见下文)。


## 贡献

我们非常高兴接受社区的贡献,这也是我们开源的主要原因!有很多方式可以贡献,即使你不是技术人士。

我们使用臭名昭著的[simplified Github workflow](http://scottchacon.com/2011/08/31/github-flow.html)来接受修改(甚至内部),基本上你需要

* 创建一个与您想要解决的问题相关的问题(有利于可追溯性和交叉引用)
* 分叉存储库
* 创建一个分支(可选,分支名中包含对问题的引用)
* 改进改进改进
* 逐步提交可读性高且详细的提交消息
* 向此存储库的master分支提交pull-request

我们将负责为您的issue添加适当的标签,并在一周内(希望更少!)回答您遇到的问题。

如果您不熟悉开源工作流程或我们的技术集合,请不要犹豫,寻求帮助!我们可以指导您或提出好的first bugs(在我们的问题中标记)。还欢迎您将您的名字添加到此文档的致谢部分。


### 提交bug

您可以直接在Github上报告问题,这对于我们来说是一个非常有用的贡献,因为我们缺乏对这个项目的用户测试。尽可能详细地记录重现您问题的步骤(更好的是使用截图)。


### 添加文档

我们尽力记录项目的每个使用情况,但您可以改进此文件并添加您自己的部分。


### 改进后端

你好,同行黑客,很高兴你能加入我们!我们计划在未来合理的时间内实现这些功能,你可以自由选择你想要贡献的功能,并为此声明一个问题

* 验证mimetypes,扩展名,大小,缓存等
* 定期抓取
* 为一组URL报告


### 测试

在提交任何pull-request之前,您必须确保测试通过。
您应该为任何新功能添加测试和/或bug修复。
您可以使用以下命令运行测试
```shell
$ python -m pytest tests/
```

您必须运行rabbitmq和redis才能通过测试。

提供了`docker-compose.yml`文件,以便快速准备好
```shell
$ docker-compose up -d
创建croquemort_redis_1...
创建croquemort_rabbitmq_1...
$ python -m pytest tests/
```

如果您使用自己的具有不同配置的中介件,
您可以将此配置作为pytest命令行参数传递
```shell
python -m pytest tests/ --redis-uri=redis://myredis:6379/0 --amqp-uri=amqp://john:doe@myrabbit
```

阅读 py.test 帮助以查看所有可用选项
```shell
python -m pytest tests/ --help
```


## 版本控制

版本号遵循 [语义版本控制](http://semver.org/) 方法。


## 许可证

我们使用 [MIT 许可证](https://tldrlegal.com/license/mit-license)。


## 致谢

* [David Larlet](https://larlet.fr/david/)
* [Alexandre Bulté](http://alexandre.bulte.net/)

# 变更日志

## 2.1.0 (2019-05-07)

- 修复 HEAD 超时处理 [#95](https://github.com/opendatateam/croquemort/pull/95)
- 删除主页/仪表盘 [#140](https://github.com/opendatateam/croquemort/pull/140)

## 2.0.4 (2018-01-24)

- 修复打包和其他增强 [#49](https://github.com/opendatateam/croquemort/pull/49)

## 2.0.3 (2018-01-08)

- 修复 setup.py

## 2.0.2 (2018-01-08)

- 修复 Circle 上的发布作业

## 2.0.1 (2018-01-08)

- 添加打包工作流程,在 Pypi 上发布

## 2.0.0 (2017-10-23)

从 `1.0.0` 到 `2.0.0` 的强制迁移

```bash
# 启动迁移服务 - 日志将在此显示
nameko run croquemort.migrations --config config.yaml
# 在另一个终端会话中
nameko shell
>>> n.rpc.migrations.migrate_from_1_to_2()
```

### 破坏性变更

- Redis DB 中的哈希前缀
[#26](https://github.com/opendatateam/croquemort/issues/26)
— 相关迁移:`add_hash_prefixes`
- 重定向支持
[#1](https://github.com/opendatateam/croquemort/issues/1)
— 相关迁移:`migrate_urls_redirect`

### 新功能

- Webhook 支持
[#24](https://github.com/opendatateam/croquemort/issues/24)

### 其他

- 优先使用 logging 替换 logbook
[#29](https://github.com/opendatateam/croquemort/issues/29)

## 1.0.0 (2017-01-23)

- 初始版本



项目详情


下载文件

下载适合您平台的文件。如果您不确定要选择哪个,请了解更多关于 安装包 的信息。

源代码分布

本发布没有可用的源代码分布文件。请参阅 生成分布存档的教程

构建分布

croquemort-2.1.0-py3-none-any.whl (30.1 kB 查看哈希)

上传时间 Python 3

支持者:

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面