2015-06-25 16 views
5

Tôi đang cố gắng để lặp qua các nội dung văn bản của một cây con bằng elt.itertext() (v3.5.0b1) như sau:lxml từ .itertext() "ValueError: đối tượng đầu vào không có yếu tố: HtmlComment"

import lxml.html.soupparser as soupparser 
import requests 

doc = requests.get("http://f10.5post.com/forums/showthread.php?t=1142017").content 
tree = soupparser.fromstring(doc) 

nodes = tree.getchildren() 

for elt in nodes: 
    for t in elt.itertext(): 
     print t 

Nhưng tôi tiếp tục nhận được một lỗi nói

File "src/lxml/iterparse.pxi", line 248, in lxml.etree.iterwalk.__init__ (src/lxml/lxml.etree.c:134032) 
File "src/lxml/apihelpers.pxi", line 67, in lxml.etree._rootNodeOrRaise (src/lxml/lxml.etree.c:15220) 
ValueError: Input object has no element: HtmlComment 

có cách nào để bỏ qua tất cả các bình luận HTML? Ngoài ra, lỗi này thực sự có ý nghĩa gì?

Cảm ơn

+0

Không chắc nếu có bất kỳ cách built-in để làm điều đó trừ khi bạn sử dụng một @AndyG PullParser – AndyG

+0

Tôi tự hỏi tại sao lxml chuyến đi qua trong trường hợp cụ thể này. Hy vọng rằng tôi sẽ không cần phải bỏ qua các bình luận HTML để tránh lỗi này. – Kar

+0

Tôi chưa sử dụng thư viện đó, nhưng tôi nghĩ bạn có thể thực hiện những gì bạn cần một cách dễ dàng với [BeautifulSoup] (https://pypi.python.org/pypi/beautifulsoup4) – rll

Trả lời

0

Điều này là bình thường.

>>> from lxml import etree 
>>> doc = ''' 
... <html><!-- PAGENAV POPUP --> 
...  <div class="vbmenu_popup" id="pagenav_menu" style="display:none"> 
...    <table cellpadding="4" cellspacing="1" border="0"> 
...    <tr> 
...      <td class="thead" nowrap="nowrap">Go to Page...</td> 
...    </tr> 
...    <tr> 
...      <td class="vbmenu_option" title="nohilite"> 
...      <form action="index.php" method="get" onsubmit="return this.gotopage()" id="pagenav_form"> 
...        <input type="text" class="bginput" id="pagenav_itxt" style="font-size:11px" size="4" /> 
...        <input type="button" class="button" id="pagenav_ibtn" value="Go" /> 
...      </form> 
...      </td> 
...    </tr> 
...    </table> 
...  </div> 
... <!--/PAGENAV POPUP --> 
... </html>''' 
>>> root = etree.fromstring(doc) 
>>> nodes = root.getchildren() 
>>> nodes 
[<!-- PAGENAV POPUP -->, <Element div at 0x10367f290>, <!--/PAGENAV POPUP -->] 
>>> for elt in nodes: 
...  for t in elt.itertext(): 
...   print t 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    File "lxml.etree.pyx", line 1406, in lxml.etree._Element.itertext (src/lxml/lxml.etree.c:48845) 
    File "lxml.etree.pyx", line 2763, in lxml.etree.ElementTextIterator.__cinit__ (src/lxml/lxml.etree.c:64747) 
    File "iterparse.pxi", line 219, in lxml.etree.iterwalk.__init__ (src/lxml/lxml.etree.c:125303) 
    File "apihelpers.pxi", line 72, in lxml.etree._rootNodeOrRaise (src/lxml/lxml.etree.c:13689) 
ValueError: Input object has no element: lxml.etree._Comment 

Như bạn thấy ở trên

>>> nodes 
[<!-- PAGENAV POPUP -->, <Element div at 0x10367f290>, <!--/PAGENAV POPUP -->] 

Note: getChildren bị phản đối. Bạn có thể sử dụng danh sách.

>>> list(root) 
[<!-- PAGENAV POPUP -->, <Element div at 0x10367f290>, <!--/PAGENAV POPUP -->] 

Các nút là danh sách các yếu tố . Nếu bạn kiểm tra như thế nào itertext() đang làm việc:

Creates a text iterator. The iterator loops over this element and all subelements, in document order, and returns all inner text.

Mặt khác nếu thay vì lặp lại trong danh sách, tôi đã lặp lại trực tiếp trên phần tử gốc với:

>>> for t in root.itertext(): 
...  print t 
... 

tôi nhận được tất cả các văn bản và rất nhiều không gian. :)

nếu bạn vẫn muốn lặp lại trên danh sách các nút. Bạn có thể suy ra thiên nhiên với

>>> [item.tag for item in nodes] 
[<built-in function Comment>, 'div', <built-in function Comment>] 

Bạn cũng có thể làm

>>> [item.__class__ for item in nodes] 
[<type 'lxml.etree._Comment'>, <type 'lxml.etree._Element'>, <type 'lxml.etree._Comment'>] 
Các vấn đề liên quan