1

在抓取这个阿富汗页面时,我收到一条错误消息:

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

但是在抓取阿根廷页面时,代码运行良好。

有什么方法可以判断是否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
4

2 回答 2

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>

这就是为什么你会得到一个奇数来组合成对。结果是将数字改造成不相关的名称,即使它最终有一个偶数。

阿根廷工作得很好,因为他们在那里没有额外的宽度属性。

这很痛苦,因为现在您知道他们不只是像任何理智的人那样从模板中填充这些表格。至少有人在摆弄其中的一些。

在尝试解析这些类型的页面时,您将不得不更加防御性地编写代码。

于 2013-06-07T05:26:44.437 回答
1

严格来说,filter不返回列表不是问题的根源(除了它可能会过滤掉您不想被过滤掉的项目),而是您的chunks函数中的错误。构造函数采用长度为 2dict迭代器的迭代器。您的函数并不总是返回对(如果列表中有奇数个项目)。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
于 2013-06-07T05:12:19.830 回答