Python 循环其中一行代码异常如何继续执行后续代码?而不是跳过当前循环

2022-09-21 18:32:47 +08:00
 chunhai

在 for 循环中一行代码抛出异常,接着执行下一行代码如何实现?而不是跳过本次循环

我写的一个爬虫,读取书籍的信息,有的书只有部分数据有,所以造成有的对象不存在而出错。 我也想过在赋值之前先判断,但是感觉有点麻烦,想找找别的写法。 下面的代码中,如果 pubulisher 读取出错,那么后面的 author 他也不会读了直接跳下一个循环了

for i in rows:
    
    try:
        book = {}
        tmp = i.find("h3", {"itemprop": "name"})
        book['title'] = tmp.text.strip()
        book['cover'] = i.find("img")['data-src']
        book['url'] = lib_url+tmp.a['href']
        book['publisher'] = i.find("a", {"title": "Publisher"}).text.strip()
        book['author'] = i.find("a", {"itemprop": "author"}).text.strip()
        detail = i.find("div", {"class": "bookDetailsBox"})
        book['year'] = detail.find("div", {"class": "property_year"}).find(
            "div", {"class": "property_value"}).text
        book['language'] = detail.find("div", {"class": "text-capitalize"}).text
    except AttributeError:
        pass
    print(book)

2362 次点击
所在节点    Python
11 条回复
dorothyREN
2022-09-21 19:00:14 +08:00
一行一个 try
chunhai
2022-09-21 19:19:42 +08:00
@dorothyREN 不够 pythonic 啊
dorothyREN
2022-09-21 19:23:35 +08:00
@chunhai #2 pythonic 又不能当饭吃
shinonome
2022-09-21 19:56:33 +08:00
我的能力范围内就是会出错的地方就 try
ClericPy
2022-09-21 20:54:58 +08:00
1. 把安全字段放前面啊
2. 不好看你包个函数起码就好看了, 比如 find 方法给它装饰器魔改一下传回个默认值( Null 对象模式 )
3. 直接改面向对象, 不安全的对象里 catch 住
4. 如果是工作中遇到的, 不要过早优化, 如果是写着玩就无所谓了, 多看看 Cookbook 和 Fluent Python 吧
secondwtq
2022-09-21 21:21:10 +08:00
试试 On Error Resume Next
filwaline
2022-09-21 21:25:46 +08:00
每一个数据查询都要单独处理不存在的情况,而不是摆在一起等异常抛出。

比如 `language`:
``
language_result = detail.find("div", {"class": "text-caplitalize"})
book["language"] = language_result and language_result.text
``

借助短路逻辑,判断 language 有没有查询到,在有的前提下才取出 text 属性,否则自然就得到了 None ,而不是抛出错误。
krixaar
2022-09-22 09:12:16 +08:00
因为要的全都是 text ,就不要 tmp 和 detail 了,全部都改成 i.find(),因为 soup.find 找不到的时候返回 None ,这样,第一轮执行下来 book 的值要么是 None 要么是找到的 tag ,最后只要一行 dictionary comprehension ,对非 None 的取 text ,就拿到了所有的 text ,再对 url 单独处理一下。
如果 i 有可能 None ,那就在最前面加 guard clause ,i 不能.find 的时候 continue 。
这样基本上就不用 try 了。
LindsayZhou
2022-09-22 17:03:03 +08:00
那就不抛错误。
这样?
``` python
book['publisher'] = getattr(
i.find("a", {"title": "Publisher"}),
'text',
'').strip()
```
LindsayZhou
2022-09-22 17:24:54 +08:00
想到还可以用海象表达式这么玩:
``` python
book['publisher'] = '' if (y:=i.find("a", {"title": "Publisher"})) is None else y.text.strip()
```
fbichijing
2022-09-22 21:51:52 +08:00
def format_text(obj):
if not obj:
return None
return obj.text.strip()

直接搞个函数套上就行了。用 find 应该是 BeautifulSoup 的,find 本身找不到表达式会返回 None ,所以出问题的部分是你获取数值时没有考虑空的情况造成的异常。

如果我自己在写可能会考虑这种方式,感觉方便但是没有点语法雅观。但相比去改变模块里面的数据格式,可能这种来得更简单直接一些。印象中以前写 xpath 时就是这么弄的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/881950

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX