在抓取此Afghanistan page时,我收到错误消息:
Traceback (most recent call last):
File "extract_table.py", line 23, in <module>
li = dict(chunks([i.text for i in all_td], 2))
ValueError: dictionary update sequence element #28 has length 1; 2 is required
但是在抓取Argentina page时,代码运行正常。
如果all_td
已返回新列表,有没有办法告诉我们?我想知道python中要使用哪些函数。
像这样的伪代码:
if all_td is new list,
execute dict(chunks([i.text for i in all_td], 2))
else
execute dict(chunks([i.text for i in areatable.findAll('td')], 2))
我想要完成的是将代码运行到阿富汗和阿根廷这两个国家。
这是我的代码
from bs4 import BeautifulSoup
import urllib2
import re
url = "http://www.howtocallabroad.com/afghanistan" # argentina works fine
html_page = urllib2.urlopen(url)
soup = BeautifulSoup(html_page)
areatable = soup.find('table',{'id':'codes'})
if areatable is None:
print "areatable is None"
else:
d = {}
def chunks(l, n):
return [l[i : i + n] for i in range(0, len(l), n)]
all_td = areatable.findAll('td')
all_td = filter(lambda x: x.attrs == {}, all_td)
print ">>>>> all_td=", all_td
li = dict(chunks([i.text for i in all_td], 2))
print ">>>>> li=", li
答案 0 :(得分:2)
您的过滤器正在删除这3个名称,因为.attrs != {}
<tr>
<td width="25%">Badghis</td>
<td>41</td>
<td width="25%">Kabul</td>
<td>20</td>
<td width="25%">Panjshar</td>
<td>28</td>
</tr>
这就是为什么你得到一个奇怪的数字来成对成对。结果就是将数字修改为不相关的名字,即使它最终有一个偶数。
阿根廷工作正常,因为他们没有额外的宽度属性。
这很痛苦,因为现在你知道他们不仅仅是像任何理智的人那样从模板中填充这些表。有人手动摆弄至少其中一些。
在尝试解析这些类型的页面时,您必须更加防御性地编写代码。
答案 1 :(得分:1)
严格地说,filter
没有返回列表不是你的问题的根源(除了事实,它可能过滤掉你不想被过滤掉的项目),但是一个错误你的chunks
功能。 dict
构造函数采用可迭代的 length 2 的迭代。您的函数chunks
并不总是返回对(如果列表具有奇数项目)。
示例:的
In [1]: def chunks(l, n):
...: return [l[i : i + n] for i in range(0, len(l), n)]
In [2]: a = chunks(range(4), 2) # even number of elements
In [3]: b = chunks(range(5), 2) # odd number of elements
In [4]: a
Out[4]: [[0, 1], [2, 3]]
In [5]: b
Out[5]: [[0, 1], [2, 3], [4]] # <-- note the trailing [4] at position 2
In [6]: dict(b)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-6-57f7c289a3e5> in <module>()
----> 1 dict(b)
ValueError: dictionary update sequence element #2 has length 1; 2 is required