在 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)
1
dorothyREN 2022-09-21 19:00:14 +08:00
一行一个 try
|
2
chunhai OP @dorothyREN 不够 pythonic 啊
|
3
dorothyREN 2022-09-21 19:23:35 +08:00
@chunhai #2 pythonic 又不能当饭吃
|
4
shinonome 2022-09-21 19:56:33 +08:00
我的能力范围内就是会出错的地方就 try
|
5
ClericPy 2022-09-21 20:54:58 +08:00 1
1. 把安全字段放前面啊
2. 不好看你包个函数起码就好看了, 比如 find 方法给它装饰器魔改一下传回个默认值( Null 对象模式 ) 3. 直接改面向对象, 不安全的对象里 catch 住 4. 如果是工作中遇到的, 不要过早优化, 如果是写着玩就无所谓了, 多看看 Cookbook 和 Fluent Python 吧 |
6
secondwtq 2022-09-21 21:21:10 +08:00
试试 On Error Resume Next
|
7
filwaline 2022-09-21 21:25:46 +08:00 1
每一个数据查询都要单独处理不存在的情况,而不是摆在一起等异常抛出。
比如 `language`: `` language_result = detail.find("div", {"class": "text-caplitalize"}) book["language"] = language_result and language_result.text `` 借助短路逻辑,判断 language 有没有查询到,在有的前提下才取出 text 属性,否则自然就得到了 None ,而不是抛出错误。 |
8
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 了。 |
9
LindsayZhou 2022-09-22 17:03:03 +08:00
那就不抛错误。
这样? ``` python book['publisher'] = getattr( i.find("a", {"title": "Publisher"}), 'text', '').strip() ``` |
10
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() ``` |
11
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 时就是这么弄的。 |