使用 python 请求数据框中的多个 url

问题描述 投票:0回答:3

我有一个使用 pandas 读取的 CSV,看起来像:

                |    URL            | Status Code | 
--------------- | ------------------|-------------|
       0        | www.example.com   |    404      |
----------------|-------------------|-------------|
        1       | www.example.com/2 |   404       |

我想检查第二列上的 URL 是否仍然响应 404。我有以下代码:

url = df['URL']
urlData = requests.get(url).content
rawData = pd.read_csv(io.StringIO(urlData.decode('utf-8')))
print(rawData)

我收到以下错误:

InvalidSchema:未找到“0”的连接适配器http://www.example.com

1 http://www.example.com/2

名称:URL,数据类型:对象'

我搜索了几个问题但找不到答案。如有任何帮助,我们将不胜感激。

python pandas python-requests
3个回答
4
投票

requests.get
不可广播,因此您必须使用
pandas.DataFrame.apply
:

为每个 URL 调用它
>>> df['New Status Code'] = df.URL.apply(lambda url: requests.get(url).status_code)
>>> df
   Status Code                URL  New Status Code
0          404    www.example.com              404
1          404  www.example.com/2              404

或使用

numpy.vectorize
:

>>> vectorized_get = numpy.vectorize(lambda url: requests.get(url).status_code)
>>> df['New Status Code'] = vectorized_get(df.URL)

0
投票

df['URL'] 将返回一系列数据,而不是单个值。我怀疑你的代码在 requests.get(url).content 行上崩溃了。

您可以发布更多代码吗?

您可能想查看 apply 函数:https://pandas.pydata.org/pandas-docs/stable/ generated/pandas.DataFrame.apply.html.


0
投票

如果您使用的是 jupyter 笔记本,您可以轻松使用

pandas-aiohttp
(免责声明;我刚刚发布了这个包);

import pandas as pd
import pandas_aiohttp

example_urls = pd.Series([
    "https://jsonplaceholder.typicode.com/posts/1",
    "https://jsonplaceholder.typicode.com/posts/2",
])

data = await example_urls.aiohttp.get_text()
0    {\n  "userId": 1,\n  "id": 1,\n  "title": "sun...
1    {\n  "userId": 1,\n  "id": 2,\n  "title": "qui...
dtype: object

注意:您可以在

assert pandas_aiohttp
之后的行中添加
import pandas_aiohttp
,以防止 IDE 突出显示明显“未使用的导入”。这个包的工作原理是注册一个自定义访问器(即猴子修补,我觉得这是可以的,因为 pandas 将其记录为一个功能)

如果您不在 jupyter 笔记本中,那么需要做一些额外的工作来启动您自己的异步事件循环:

import pandas as pd
import pandas_aiohttp
import asyncio

example_urls = pd.Series([
    "https://jsonplaceholder.typicode.com/posts/1",
    "https://jsonplaceholder.typicode.com/posts/2",
])

async def main():
    data = await example_urls.aiohttp.get_text()
    print(data)

asyncio.run(main())

默认情况下,这将使用 100 个并行连接,并且应该比大多数其他方法快得多。

© www.soinside.com 2019 - 2024. All rights reserved.