我正在使用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
........................
但是我发现即使在没有错误情况有效的情况下,也会选择“无效”选项。我究竟做错了什么?
答案 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()));
}