循环通过条件字典时的逻辑评估错误

时间:2016-12-13 20:48:57

标签: python scrapy

我正在使用Scrapy循环浏览网页列表。我刮的一些页面是错误的。我想跟踪各种错误类型,所以我设置了我的函数,首先检查一系列错误条件(我放在字典中是否为真,如果没有进行正常的页面抓取:

def parse_detail_page(self, response):

    error_value = False
    output = ""

    error_cases = {

        "' pageis not found' in response.body" : 'invalid',

        "'has been transferred' in response.body" : 'transferred',
    }

    for key, value in error_cases.iteritems():
        if bool(key):
            error_value = True
            output = value

    if error_value:
        for field in J1_Item.fields:
            if field == 'case':
                item[field] = id
            else:
                item[field] = output

    else:
        item['case'] = id
        ........................

但是我发现即使在没有错误情况有效的情况下,也会选择“无效”选项。我究竟做错了什么?

4 个答案:

答案 0 :(得分:1)

bool(key)会将键从字符串转换为bool。

它不会做的是实际评估条件。您可以使用eval(),但我建议改为存储一个函数列表(每个函数返回一个对象或抛出一个异常),而不是当前的dict-with-string-keys-实际上是Python-代码。

答案 1 :(得分:1)

我不确定你为什么要像你一样评估bool(关键)。我们来看看你的error_cases。您有两个键和两个值。第一次"' pageis not found' in response.body"将是您的密钥,"'has been transferred' in response.body"将成为您的for循环中第二轮的关键。当你检查bool(key)时,这些都不会是假的,因为key的值不是False或0。

>>> a = "' pageis not found' in response.body"
>>> bool(a)
True

你需要在bool(key)之外设置一个不同的评估器,否则你总会出错。

答案 2 :(得分:1)

不评估您的条件(True)。相反,您要评估非空字符串的真值,即def parse_detail_page(self, response): error_value = False output = "" error_cases = { "pageis not found" : 'invalid', "has been transferred" : 'transferred', } for key, value in error_cases.iteritems(): if key in response.body: error_value = True output = value break .................

这可能有效:

fatal error: mcrypt.h: No such file or directory
#include <mcrypt.h>
                   ^

(必须是&#34;未找到网页&#34;或&#34;找不到网页&#34;?)

答案 3 :(得分:1)

您的条件是字符串,因此不会对其进行评估。 您可以使用from operator import contains class ...: def parse_detail_page(self, response): error_value = False output = "" error_cases = [ {'search': ' pageis not found', 'operator': contains, 'output': 'invalid' }, {'search': 'has been transferred', 'operator': contains, 'output': 'invalid' }, ] for error in error_cases: if error['operator'](error['search'], response.body): error_value = True output = error['output'] print output if error_value: for field in J1_Item.fields: if field == 'case': item[field] = id else: item[field] = output else: item['case'] = id ... 函数评估字符串,这非常不安全。

polyfill模块的帮助下,无需评估不安全的字符串(只要您的条件非常简单)。

错误[&#39;运营商&#39;]保留对&#39;包含&#39;的引用功能,可用作替换&#39; in&#39;。

public Map<String, Path> createMap(Path sourceFolder, PathMatcher filter) {
    return stream.filter(filter::matches)
                 .collect(Collectors.toMap(path -> FilenameHelper.parseFilename(path.toFile().getName()), Function.identity()));
}