跳转到主要内容

Scrapinghub 自动提取 API 的 Python 接口

项目描述

PyPI Version Supported Python Versions Build Status Coverage report

Python 客户端库,用于Scrapinghub AutoExtract API。它允许从任何网站提取产品、文章、招聘信息等数据 - 不论API是否支持。

此软件包提供了命令行实用程序、基于asyncio的库以及一个简单的同步包装器。

许可证是BSD 3条款。

安装

pip install scrapinghub-autoextract

scrapinghub-autoextract 需要 Python 3.6+ 以运行 CLI 工具和 asyncio API;基本、同步 API 可以在 Python 3.5 上运行。

使用方法

首先,请确保您有一个API密钥。为了避免在每次调用时都通过 api_key 参数传递它,您可以将 SCRAPINGHUB_AUTOEXTRACT_KEY 环境变量设置为密钥。

命令行界面

使用客户端最基本的方式是通过命令行。首先,创建一个包含URLs的文件,每行一个URL(例如 urls.txt)。其次,设置环境变量 SCRAPINGHUB_AUTOEXTRACT_KEY 为您的AutoExtract API密钥(您也可以通过 --api-key 脚本参数传递API密钥)。

然后运行一个脚本来获取结果

python -m autoextract urls.txt --page-type article --output res.jl

如果您需要更多灵活性,可以通过创建一个包含查询的JsonLines文件来自定义请求:每行一个JSON对象。您可以在那里传递任何AutoExtract选项。示例 - 存储在 queries.jl 文件中

{"url": "http://example.com", "meta": "id0", "articleBodyRaw": false}
{"url": "http://example.com/foo", "meta": "id1", "articleBodyRaw": false}
{"url": "http://example.com/bar", "meta": "id2", "articleBodyRaw": false}

请参阅 API 文档 了解这些查询字典中所有支持参数的描述。API文档中提到了批量请求及其限制(每次最多100个查询);这些限制不适用于queries.jl文件(即它可能有数百万行),因为命令行脚本会自行进行分批。

请注意,在示例中省略了 pageType 参数;pageType 值会自动从 --page-type 命令行参数值中填充。您也可以在 queries.jl 文件中为行设置不同的 pageType;它具有高于通过命令行传递的 --page-type 的优先级。

要为这个 queries.jl 文件获取结果,请运行

python -m autoextract --intype jl queries.jl --page-type article --output res.jl

处理速度

每个API密钥都有RPS的限制。为了更快地处理您的URL,您可以调整并发选项:批量大小和连接数。

最佳选项取决于RPS限制以及您从中提取数据的网站。例如,如果您的API密钥的限制为3RPS,并且您观察到的网站的平均响应时间为10秒,那么为了达到这3RPS,您可以设置例如批量大小=2,连接数=15 - 这将允许并行处理30个请求。

要在CLI中设置这些选项,请使用 --n-conn--batch-size 参数

python -m autoextract urls.txt --page-type articles --n-conn 15 --batch-size 2 --output res.jl

如果并行处理太多的请求,您将收到节流错误。它们会被CLI自动处理,但它们会使提取效率降低;请调整并发选项以减少节流错误(HTTP 429)的发生频率。

您可能还会受到网站速度的限制。AutoExtract会尽量避免对单个网站造成太大的压力,但最好在客户端也限制这一点。如果您正在从单个网站提取数据,减少并行请求的数量可能是合理的;这可以确保整体成功率更高。

如果您正在从多个网站提取数据,合理地分配时间负载是有意义的:如果您有网站A、B和C,不要按AAAABBBBCCCC的顺序发送请求,而是按ABCABCABCABC的顺序发送。

为此,您可以更改输入文件中查询的顺序。或者,您可以通过传递 --shuffle 选项;它会在发送到API之前随机打乱输入查询。

python -m autoextract urls.txt –shuffle –page-type articles –output res.jl

运行 python -m autoextract --help 以获取所有支持选项的描述。

错误

在请求过程中可能会发生以下错误

某些错误可以重试,而其他错误则不能。

例如,你可以重试由于代理超时错误而失败的查询,因为这通常是临时错误,下一次重试时可能会有不同的响应。

另一方面,重试返回404 Not Found错误的查询是没有意义的,因为重试后响应不应该改变。

重试

默认情况下,我们将自动重试网络和请求级别的错误。你也可以通过指定--max-query-error-retries参数来启用查询级别错误的重试。

如果你希望提高成功率,可以通过增加执行更多请求的代价来启用查询级别的重试。

python -m autoextract urls.txt --page-type articles --max-query-error-retries 3 --output res.jl

失败的查询将重试,直到达到最大重试次数或超时。如果仍然无法无错误地获取所有查询,最后可用的结果将被写入输出,包括成功和失败的查询。

同步API

同步API提供了一个尝试自动提取的简单方法。对于生产使用,强烈推荐使用asyncio API。目前,同步API不处理节流错误,并具有其他限制;它最适合快速检查几个URL的提取结果。

要发送请求,请使用request_raw函数;查阅API文档了解如何填充查询

from autoextract.sync import request_raw
query = [{'url': 'http://example.com.foo', 'pageType': 'article'}]
results = request_raw(query)

请注意,如果查询中有多个URL,结果可以按任意顺序返回。

还有一个autoextract.sync.request_batch辅助函数,它接受URL和页面类型,并确保结果与请求的URL顺序相同

from autoextract.sync import request_batch
urls = ['http://example.com/foo', 'http://example.com/bar']
results = request_batch(urls, page_type='article')

asyncio API

基本用法与同步API(request_raw)类似,但使用asyncio事件循环

from autoextract.aio import request_raw

async def foo():
    query = [{'url': 'http://example.com.foo', 'pageType': 'article'}]
    results1 = await request_raw(query)
    # ...

还有一个request_parallel_as_completed函数,它允许并行处理许多URL,使用批处理和多个连接

import sys
from autoextract.aio import request_parallel_as_completed, create_session
from autoextract import ArticleRequest

async def extract_from(urls):
    requests = [ArticleRequest(url) for url in urls]
    async with create_session() as session:
        res_iter = request_parallel_as_completed(requests,
                                    n_conn=15, batch_size=2,
                                    session=session)
        for fut in res_iter:
            try:
                batch_result = await fut
                for res in batch_result:
                    # do something with a result, e.g.
                    print(json.dumps(res))
            except RequestError as e:
                print(e, file=sys.stderr)
                raise

request_parallel_as_completed基于asyncio.as_completed(请参阅https://docs.pythonlang.cn/3/library/asyncio-task.html#asyncio.as_completed),实际上在底层使用它。

注意from autoextract import ArticleRequest及其在上面的示例中的用法。有几个请求辅助类,可以简化查询的构建。

request_parallel_as_completedrequest_raw函数处理节流(http 429错误)和网络错误,在这些情况下重试请求。

CLI接口实现(autoextract/__main__.py)可以作为使用示例。

请求辅助类

要查询自动提取,你需要创建一个包含请求参数的字典,例如。

{'url': 'http://example.com.foo', 'pageType': 'article'}

为了简化库的使用并避免错误,scrapinghub-autoextract提供了用于构建这些字典的辅助类

* autoextract.Request
* autoextract.ArticleRequest
* autoextract.ProductRequest
* autoextract.JobPostingRequest

你可以传递这些类的实例而不是字典来代替任何接受请求字典的地方。所以例如,你不需要这样写

query = [{"url": url, "pageType": "article"} for url in urls]

你可以这样写

query = [Request(url, pageType="article") for url in urls]

或者这样写

query = [ArticleRequest(url) for url in urls]

有一个区别:当使用Request或其变体时,articleBodyRaw参数默认设置为False,而API中默认设置为True

你可以通过传递包含额外数据的字典来覆盖API参数,使用extra参数。请注意,它将覆盖使用标准属性(如articleBodyRawfullHtml)所做的任何先前配置。

额外参数示例

request = ArticleRequest(
    url=url,
    fullHtml=True,
    extra={
        "customField": "custom value",
        "fullHtml": False
    }
)

这将生成一个看起来像这样的查询

{
    "url": url,
    "pageType": "article",
    "fullHtml": False,  # our extra parameter overrides the previous value
    "customField": "custom value"  # not a default param but defined even then
}

贡献

使用 tox 以不同版本的 Python 运行测试

tox

上述命令还运行类型检查;我们使用 mypy。

变更

0.6.1 (2021-01-27)

  • 修复了 max_retries 的行为。总尝试次数必须是 max_retries + 1

0.6.0 (2020-12-29)

  • CLI 变更:进度条中的错误显示已更改;执行后打印摘要

  • 启用重试时,将重试更多错误,从而提高成功率

  • 修复了 TCP 连接池

  • autoextract.aio.request_raw 函数允许向 API(而非远程网站)传递自定义头信息

  • autoextract.aio.request_raw 现在允许通过 retrying 参数自定义重试行为

  • tenacity.RetryError 不再由库引发;而是引发具体的错误

  • Python 3.9 支持

  • CI 已从 Travis 移动到 Github Actions

0.5.2 (2020-11-27)

  • QueryError 已重命名为 _QueryError,因为这不是库用户会看到的错误。

  • 由于 userQuery API 输出中的 userAgent 导致重试失败;已添加临时解决方案以使重试再次工作。

0.5.1 (2020-08-21)

  • 修复了当 endpoint 参数为 None 时阻止调用 request_raw 的问题

0.5.0 (2020-08-21)

  • --api-endpoint 选项添加到命令行实用工具

  • 通过添加关于 Request 的额外参数的详细信息来改进文档

0.4.0 (2020-08-17)

autoextract.Request 辅助类现在允许为 AutoExtract 请求设置任意参数 - 可以通过 extra 参数传递。

0.3.0 (2020-07-24)

在此版本中,添加或改进了与重试相关的功能。现在可以通过启用查询级别的重试来修复一些临时错误,并且默认的重试行为已得到改进。

  • 不向后兼容:autoextract.aio.ApiError 已重命名为 autoextract.aio.RequestError

  • max_query_error_retries 参数添加到 autoextract.aio.request_rawautoextract.aio.request_parallel_as_completed 函数;它允许启用 API 返回的临时查询级别错误的重试

  • CLI:添加 --max-query-error-retries 选项以重试临时查询级别错误。

  • 现在将重试来自服务器的 HTTP 500 错误;

  • 改进了文档和测试。

0.2.0 (2020-04-15)

  • 重写 asyncio API,以简化需要传递元数据的场景的使用。添加了 autoextract.aio.request_parallel_as_completed,移除了 autoextract.aio.request_parallelautoextract.aio.request_batch

  • CLI:现在显示各种统计信息:平均响应和连接时间,% 的节流错误,% 的网络和其他错误

  • CLI:新 --intype jl 选项允许处理任意 AutoExtract API 查询的 .jl 文件

  • CLI:新 --shuffle 选项允许打乱输入数据,以更均匀地分布在网站上。

  • CLI:它不再在不可恢复的错误发生时退出,以帮助长期运行的处理任务。

  • 调整重试逻辑以更好地处理网络错误。

  • autoextract.aio.request_rawautoextract.aio.request_parallel_as_completed 函数提供了返回请求统计信息的接口,包括重试。

  • autoextract.Request, autoextract.ArticleRequest, autoextract.ProductRequest, autoextract.JobPostingRequest 辅助类

  • 改进文档。

0.1.1 (2020-03-12)

  • 每批允许最多100个元素,而不是最多99个

  • 添加了自定义User-Agent头

  • 声明并测试了Python 3.8支持

0.1 (2019-10-09)

初始发布。

项目详情


下载文件

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

源代码发行版

scrapinghub-autoextract-0.6.1.tar.gz (30.3 kB 查看哈希值)

上传时间 源代码

构建发行版

scrapinghub_autoextract-0.6.1-py3-none-any.whl (23.7 kB 查看哈希值)

上传时间 Python 3

由以下支持