跳转到主要内容

Python接口用于Zyte自动提取API

项目描述

PyPI Version Supported Python Versions Build Status Coverage report

Python客户端库,用于Zyte自动提取API。它允许从任何支持API的网站提取产品、文章、职位发布等信息。

此包提供了命令行工具、基于asyncio的库和一个简单的同步包装器。

许可协议为BSD 3条款。

安装

pip install zyte-autoextract

zyte-autoextract需要Python 3.6+用于CLI工具和asyncio API;基本、同步API与Python 3.5兼容。

用法

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

命令行界面

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

然后运行脚本以获取结果

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

如果您需要更多的灵活性,可以通过创建一个包含查询的JsonLines文件来自定义请求:每行一个JSON对象。您可以在其中传递任何Zyte自动提取选项。例如,将其存储在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;它优先于通过cmdline传递的--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)。

您可能还受到网站速度的限制。Zyte自动提取会尽量避免对单个网站造成过大压力,但最好在客户端也进行限制。如果您从单个网站提取数据,减少并行请求的数量可能更有意义;这可以提高整体的成功率。

如果您从多个网站提取数据,合理地分配时间负载是有意义的:如果您有网站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提供了一个简单的方式来尝试Zyte自动提取。对于生产使用,强烈建议使用异步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)类似,但使用异步事件循环

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)可以作为使用示例。

请求辅助类

要查询Zyte自动提取,您需要创建一个带有请求参数的字典,例如。

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

为了简化库的使用并避免打字错误,zyte-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.7.1 (2021-11-24)

  • 添加了 –disable-cert-validation 选项以禁用TSL证书验证。

0.7.0 (2021-02-10)

更新以适应上游的重新品牌化更改,因为Scrapinghub已成为Zyte。

此更新涉及一些重大更改

  • Python软件包索引中的存储库名称和包名称已从 scrapinghub-autoextract 更改为 zyte-autoextract

  • SCRAPINGHUB_AUTOEXTRACT_KEY 环境变量已重命名为 ZYTE_AUTOEXTRACT_KEY

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,因为这不是库用户会看到的错误。

  • 由于在用户Query 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

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

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

  • 现在会重试服务器返回的HTTP 500错误;

  • 改进了文档和测试。

0.2.0 (2020-04-15)

  • 异步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)

首次发布。

项目详情


下载文件

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

源分发

zyte-autoextract-0.7.1.tar.gz (29.7 kB 查看哈希值)

上传时间

构建分发

zyte_autoextract-0.7.1-py3-none-any.whl (24.0 kB 查看哈希值)

上传时间 Python 3

支持者