Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么requests.get()不在循环内工作,而是在循环外工作?_Python_Xml_Python Requests - Fatal编程技术网

Python 为什么requests.get()不在循环内工作,而是在循环外工作?

Python 为什么requests.get()不在循环内工作,而是在循环外工作?,python,xml,python-requests,Python,Xml,Python Requests,我使用此函数从XML中提取数据(内部网络,出于安全原因,我无法提供URL): 我希望此函数在接受param1、param2和param3的循环中工作 frames = [] for i in range(len(table_with_params)): try: param1 = int(table_with_params.loc[i, 'param1']) param2 = int(table_with_params.loc[i, 'param2'

我使用此函数从XML中提取数据(内部网络,出于安全原因,我无法提供URL):

我希望此函数在接受
param1
param2
param3
的循环中工作

frames = []

for i in range(len(table_with_params)):

    try:

        param1 = int(table_with_params.loc[i, 'param1'])
        param2 = int(table_with_params.loc[i, 'param2'])
        param3 = int(table_with_params.loc[i, 'param3'])

        data = crawl_and_get_data(url, keys, param1, param2, param3)
        frames.append(data)

    except TypeError:
        print('Whoops, something is wrong with this request.')
        continue
在大多数情况下,它是有效的,但在某些特定情况下,它不是。在执行之后,我尝试再次获取数据,但不在循环中,并且成功了

data = crawl_and_get_data(url, keys, problematic_param1, problematic_param2, problematic_param3)
# it works!
有什么提示吗?提前谢谢


编辑:跳过异常处理,返回的错误为:

TypeError: cannot convert the series to <class 'int'>
TypeError:无法将序列转换为

函数在循环外运行时不会抛出此错误。

HTTP请求失败的原因很多,有时会成功,这是一个奇迹,因此您最好为失败的请求做好准备。话虽如此,您的问题实际上可能完全在别处,而您的(相当糟糕的)异常处理正在阻止您获得任何提示

这里的第一个问题是您的try块太大了,您希望将try块限制为严格的必需值。第二个问题是,您完全忽略了实际的异常,只是打印了一条完全无用的消息

目前,在try块中主要有三个不同的部分:准备请求的参数、执行请求本身(实际上是两个请求)以及对结果进行处理。这些部分中的每一部分都可以引发自己的特定异常,因此,适当的异常处理方案应该是将每个部分放在一个不同的try块中(或者,如果您不希望有任何特殊情况,则至少在其他try块之外—“对结果做点什么”部分只是
frames.append(数据)
,它并不真正保证使用try/except块)。瞧,你想要这样的东西:

try:

    param1 = int(table_with_params.loc[i, 'param1'])
    param2 = int(table_with_params.loc[i, 'param2'])
    param3 = int(table_with_params.loc[i, 'param3'])

except TypeError as e:
    print("invalid source value at row {} : {}".format(i, e))
    continue


try:
    data = crawl_and_get_data(url, keys, param1, param2, param3)
您不应该在这里得到任何类型错误-理论上,也就是说,请参阅下文,了解您真正的问题

 except RequestError as e:
    print("Failed request for row {} : {}".format(i, e))
    continue

frames.append(data)
请注意,使用
日志记录
模块会更好,特别是因为它知道如何正确记录完整的错误回溯(通常包含非常有价值的调试信息)

还请注意:

def crawl_and_get_data(url, keys, param1, param2, param3):

    r = requests.get(url, auth = HTTPDigestAuth(keys[0], keys[1]))
如果目标是登录,并且url在外部(调用)循环中保持不变,您可能希望这样做,这可能会使查询数量减半。否则,对于您和目标服务器来说,这会有点浪费时间、带宽和cpu周期。请善待服务器的所有者

    xml_url = 'http://www.sitetogetdata.com/xml/?param1=' + param1 + '&param2=' + param2 + '&param3=' + param3    
    res = requests.get(xml_url, auth = HTTPDigestAuth(keys[0], keys[1]))
现在这里有一个
TypeError
(假设您发布的是您的真实代码或足够类似的代码):您明确地将参数值转换为调用方代码中的
int
,然后尝试用字符串连接这些int。这不起作用,并引发了一个
TypeError
事实上(有很好的理由——无声地转换不兼容类型的语言会被设计破坏)

一般来说,对于这类操作,最好使用字符串格式,而不是字符串串联,即:

xml_url = '...?param1={}&param2={}&param3={}'.format(param1, param2, param3)
它不仅可读性更高,而且将调用
str()
(或者根据格式说明符调用相应的格式函数),从而避免出现
类型错误

但是HTTP查询字符串还有其他缺陷,因此您应该实际使用:

   res = requests.get(url, params={"param1": param1, "param2": param2, "param3": param3}, ....)

HTTP请求可能会失败的原因有很多,它们有时会成功是一个奇迹,所以您最好为失败的请求做好准备。话虽如此,您的问题实际上可能完全在别处,而您的(相当糟糕的)异常处理正在阻止您获得任何提示

这里的第一个问题是您的try块太大了,您希望将try块限制为严格的必需值。第二个问题是,您完全忽略了实际的异常,只是打印了一条完全无用的消息

目前,在try块中主要有三个不同的部分:准备请求的参数、执行请求本身(实际上是两个请求)以及对结果进行处理。这些部分中的每一部分都可以引发自己的特定异常,因此,适当的异常处理方案应该是将每个部分放在一个不同的try块中(或者,如果您不希望有任何特殊情况,则至少在其他try块之外—“对结果做点什么”部分只是
frames.append(数据)
,它并不真正保证使用try/except块)。瞧,你想要这样的东西:

try:

    param1 = int(table_with_params.loc[i, 'param1'])
    param2 = int(table_with_params.loc[i, 'param2'])
    param3 = int(table_with_params.loc[i, 'param3'])

except TypeError as e:
    print("invalid source value at row {} : {}".format(i, e))
    continue


try:
    data = crawl_and_get_data(url, keys, param1, param2, param3)
您不应该在这里得到任何类型错误-理论上,也就是说,请参阅下文,了解您真正的问题

 except RequestError as e:
    print("Failed request for row {} : {}".format(i, e))
    continue

frames.append(data)
请注意,使用
日志记录
模块会更好,特别是因为它知道如何正确记录完整的错误回溯(通常包含非常有价值的调试信息)

还请注意:

def crawl_and_get_data(url, keys, param1, param2, param3):

    r = requests.get(url, auth = HTTPDigestAuth(keys[0], keys[1]))
如果目标是登录,并且url在外部(调用)循环中保持不变,您可能希望这样做,这可能会使查询数量减半。否则,对于您和目标服务器来说,这会有点浪费时间、带宽和cpu周期。请善待服务器的所有者

    xml_url = 'http://www.sitetogetdata.com/xml/?param1=' + param1 + '&param2=' + param2 + '&param3=' + param3    
    res = requests.get(xml_url, auth = HTTPDigestAuth(keys[0], keys[1]))
现在这里有一个
TypeError
(假设您发布的是您的真实代码或足够类似的代码):您明确地将参数值转换为调用方代码中的
int
,然后尝试用字符串连接这些int。这不起作用,并引发了一个
TypeError
事实上(有很好的理由——无声地转换不兼容类型的语言会被设计破坏)

一般来说,对于这类操作,最好使用字符串格式,而不是字符串串联,即:

xml_url = '...?param1={}&param2={}&param3={}'.format(param1, param2, param3)
它不仅可读性更高,而且将调用
str()
(或者根据格式说明符调用相应的格式函数),从而避免出现
类型错误

但是HTTP查询字符串还有其他缺陷,因此您应该实际使用:

   res = requests.get(url, params={"param1": param1, "param2": param2, "param3": param3}, ....)

错误不是来自爬网。。它位于以下行中:

param1=int(带参数的表。