2013-08-30 38 views
1

当解析http://en.wikipedia.org/wiki/Israel我遇到一个H2标签,该标签具有文本,但美丽的汤返回None类型吧:美丽的汤没有找到字符串

$ python 
Python 2.7.3 (default, Apr 10 2013, 05:13:16) 
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import bs4 
>>> import requests 
>>> from pprint import pprint 
>>> response = requests.get('http://en.wikipedia.org/wiki/Israel') 
>>> soup = bs4.BeautifulSoup(response.content) 
>>> for h in soup.find_all('h2'): 
...  pprint(str(type(h))) 
...  pprint(h) 
...  pprint(str(type(h.string))) 
...  pprint(h.string) 
...  print('--') 
...      
"<class 'bs4.element.Tag'>" 
<h2>Contents</h2>  
"<class 'bs4.element.NavigableString'>" 
u'Contents'   
--     
"<class 'bs4.element.Tag'>" 
<h2><span class="mw-headline" id="Etymology"><span id="Etymology"></span> Etymology</span></h2> 
"<type 'NoneType'>" 
None     
--     
"<class 'bs4.element.Tag'>" 
<h2><span class="mw-headline" id="History">History</span></h2> 
"<class 'bs4.element.NavigableString'>" 
u'History'   
-- 

请注意,这不是一个解析的问题,美丽的汤解析文件很好。为什么第二个H2元素返回None类型?是否由于字符串中的前导“”(空格)?我该如何解决这个问题?这是在Python 2.7上的Beautiful Soup 4,Kubuntu Linux 12.10。

+0

二号H2有2跨度空单用id ethymology。可能bsoup失败这一个。 – 2013-08-30 14:35:49

+0

我也注意到这一点。怎么可能我围绕它编码? – dotancohen

+0

能够帮助你我需要挖掘文档,因为我从不使用bs4 - 如果你不急,我可以尝试。 – 2013-08-30 14:40:37

回答

1

我回答第一个上半年,什么是错的......

documentation of bs4引述:“如果一个标签包含一个以上的事情,那么,目前还不清楚应该是指什么.string,所以.string被定义为None“。

而现在的另一半,如何解决它。

从同一来源再次引用:“如果标签内有多个东西,您仍然可以只看字符串,使用.strings生成器。”更好的是,使用.stripped_strings生成器,连接结果,我想你会得到你想要的。

+0

'.string'/'.stripped_string'不适合我。但'.contents'正在工作并返回我需要的字符串列表。你能解释这是为什么吗? – user2831683

+0

@ user2831683你能提供一个最小的问题实例吗?在另一个问题中,如果它很长... – nickie

+0

解决了它。实际上,在我的情况bs4.element.Tag对象有太多的字符串引用,所以它不能决定要返回哪一个字符串。所以它返回'无'。在另一个问题找到确切的解决我的问题。 Thankyou – user2831683

1

我认为这是因为第二h2没有文本,而不是它有一个span作为一个孩子(和跨度有另一个孩子作为其子,这使得该h2的孙子。

对于这种基于发电机解析使用属性,如.stripped_strings.strings

>>> s.find_all('h2') 
[<h2>Contents</h2>, <h2><span class="mw-headline" id="Etymology"><span id="Etymology"></span> Etymology</span></h2>] 
>>> list(s.find_all('h2')[-1].stripped_strings) 
[u'Etymology'] 
+0

您的代码有效,但理由不正确。如果只有一个“span”(或任何嵌套的“span”列表),那就没问题了。 – nickie

+0

@nickie你的意思是跨度(而不是垃圾邮件;) – 2013-08-30 14:48:04

+0

其实,第二个'h2'确实有文字,就在''之后。但是,它看起来不是合法的HTML。 – dotancohen