如何避免尝试和排除语句的长链?

时间:2019-06-05 08:14:32

标签: python exception

我正在尝试使用Mechanize python软件包在网站上查找搜索框,以查找网页上的表单。几乎每个网站都以自己的方式定义这些形式,因此我需要搜索大量不同的签名。由于Mechanize Browser.select_form函数在找不到指定的表单时会引发异常,因此寻找许多不同的表单会变成一长串try和except语句。

我尝试过(或推入)的第一件事是以下结构。它可以工作,但是1:看起来不太好; 2:扩展不好(如果我需要更多的语句,这会造成混乱); 3:总的来说,这似乎是不好的代码。

from mechanize import Browser
br = Browser()
br.open(url)
try:
    br.select_form(id=lambda x: 'search' in x)
except Exception:
    try:
        br.select_form(class_=lambda x: 'search' in x)
    except Exception:
        try:
            br.select_form(action=lambda x: 'search' in x)
        except Exception:
            try:
                br.select_form(role=lambda x: 'search' in x)
            except Exception:
                print('NOTHING FOUND')
                pass

https://stackoverflow.com/a/6095782/11309912中所述,可能稍微好一点的解决方案是将except子句定向到函数。这样可以解决横向扩展,但仍然包含许多重复的代码。

对我来说,理想的解决方案是拥有一个可以迭代的语句列表,直到找到一种类型的表单为止。一个非常粗糙的例子是:

forms = ['id=lambda x: 'search' in x', 'class_=lambda x: 'search' in x', .....]
for form in forms:
    try:
        br.select_form(form)
        break
    except Exception:
        pass

是否可能与此类似?

3 个答案:

答案 0 :(得分:5)

唯一可变的是传递给select_form的关键字参数的名称,您可以像这样传递变量关键字:

for attr in ('id', 'search', 'class_', 'role'):
    try:
        form = br.select_form(**{attr: lambda x: 'search' in x})
        break
    except:
        pass
else:
    print('NOTHING FOUND')

答案 1 :(得分:0)

我不确定要机械化,但是我知道硒有可能。实际上,或多或少与您使用的示例完全相同。在下一个示例中,我不会使用lambda,但是它会产生相同的效果,但速度稍慢一些。假设驱动程序是我的浏览器的变量指针名称。

listOfPossibleFields = ["user", "username", "un", "name", "login"]
for word in listOfPossibleFields:
    try:
        driver.find_element_by_name(word)
    except Exception:
         pass

答案 2 :(得分:0)

如果您想要更通用的内容,则可以为每种搜索模式创建一个类,然后再考虑这些类实例的列表。

class IdSearchPattern(object):
    def search(self, *args, **kwargs):
        ...

class RoleSearchPattern(object):
    def search(self, *args, **kwargs):
        ...

search_patterns = [IdSearchPattern(), RoleSearchPattern()]
for sp in search_patterns:
    try:
        result = sp.search()
        break
    except Exception:
        pass

有时候这是一个很好的解决方案,有时甚至有点过度设计。

注意:我从手机上写了这个答案,代码未经测试。