在python中高效获取url的状态码,forloop的替代方案

2024-09-28 05:17:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我想检查一个url列表(在dataframedf的一列中)查看它们的状态代码(404403和200似乎是比较有趣的)。我定义了一个函数来完成这个任务。但是,它使用的for循环效率很低(我有一个很长的url列表!)。在

有没有人对如何更有效地做这件事有什么建议?最佳情况下,返回的状态代码也将显示在数据帧的新列中,例如df['status_code_url']。在

def url_access(df, column):
    e_404 =0
    e_403 =0
    e_200 =0
    for i in range(0, len(df)):
        if requests.head(df[column][i]).status_code == 404:
            e_404= e_404+1
        elif requests.head(df[column][i]).status_code == 403:
            e_403 = e_403 +1
        elif requests.head(df[column][i]).status_code == 200:
            e_200 = e_200 +1
        else:
            print(requests.head(df[column][i]).status_code)

    return ("Statistics about " + column , '{:.1%}'.format(e_404/len(df)) 
            + " of links to intagram post return 404", '{:.1%}'.format(e_403/len(df)) 
            + " of links to intagram post return 403", '{:.1%}'.format(e_200/len(df)) 
            + " of links to intagram post return 200")

非常感谢你!在


Tags: oftoformaturldflenreturnstatus
3条回答

使用Pandasapply和{}-

def url_access(x):
    return requests.head(x).status_code


df['Status'] = df['url'].apply(url_access)

dfcount = df.groupby('Status')['url'].count().reset_index()

基本上,你的任务似乎是:

  1. 获取url状态代码
  2. 收集所有
  3. 计算百分比

第一步使用:

def get_code(url):
    return requests.head(url).status_code

有关将此功能应用于dataframe列的第二步,请参阅 https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html

^{pr2}$

对于第三步,您可以在列上使用运算来计算百分比:

resp_df[resp_df == 404].sum() / len (resp_df) 

(注意代码未运行)

pandas.DataFrame.apply(或者更确切地说,普通的requests库)一次只能发出一个请求。要并行执行多个请求,可以使用^{}(用pip install requests-futures安装):

import pandas as pd
from requests_futures.sessions import FuturesSession

def get_request(url):
    session = FuturesSession()
    return session.head(url)


def get_status_code(r):
    return r.result().status_code

if __name__ == "__main__":
    urls = ['http://python-requests.org',
            'http://httpbin.org',
            'http://python-guide.org',
            'http://kennethreitz.com']
    df = pd.DataFrame({"url": urls})
    df["status_code"] = df["url"].apply(get_request).apply(get_status_code)

然后,您可以使用例如groupby,如their answer中的@Aritesh所建议的:

^{pr2}$

使用此功能,您可能还需要针对连接错误和超时添加一些保护:

import numpy as np
import requests

def get_request(url):
    session = FuturesSession()
    return session.head(url, timeout=1)

def get_status_code(r):
    try:
        return r.result().status_code
    except (requests.exceptions.ConnectionError, requests.exceptions.ReadTimeout):
        return 408 # Request Timeout

ips = np.random.randint(0, 256, (1000, 4))
df = pd.DataFrame({"url": ["http://" + ".".join(map(str, ip)) for ip in ips]})
df["status_code"] = df["url"].apply(get_request).apply(get_status_code)
df.groupby('status_code')['url'].count().reset_index()
#    status_code  url
# 0          200    3
# 1          302    2
# 2          400    2
# 3          401    1
# 4          403    1
# 5          404    1
# 6          408  990

相关问题 更多 >

    热门问题