【问题标题】:HTML Parsing using Python使用 Python 进行 HTML 解析
【发布时间】:2012-04-06 22:43:57
【问题描述】:

我需要解析一个网页并从中提取一些值。所以我创建了一个python解析器如下:

from HTMLParser import HTMLParser
class MyHTMLParser(HTMLParser):
    def handle_data(self, data):
        print "Data     :", data

f=open("result.html","r")
s=f.read()
parser = MyHTMLParser()
parser.feed(s)

程序读取 html 文件并从中打印数据。

我通过了以下 result.html,这里解析器工作正常

<tr class='trmenu1'>
<td>Marks Obtained: </td><td colspan=1>75.67 Out of 100</td>
</tr>
<tr class='trmenu1'>
<td>GATE Score: </td><td colspan=1>911</td>
</tr>
<tr class='trmenu1'>
<td>All India Rank: </td><td colspan=1>34</td>
</tr>

通过上面的html后输出为:

数据:

数据:获得的分数:
数据:100 个数据中的 75.67 个数据:

数据:

数据:

数据:GATE 分数:
资料 : 911
数据:

数据:

数据:

数据:全印度排名:
数据:34

但是解析器应该读取一个更大的文件,而上面提到的代码只是那个大文件的一小部分。文件太大,无法在此处粘贴。所以我把它上传到以下链接:http://www.mediafire.com/?dsgr1gdjvs59c7c 当传递较大的文件时,解析器不会读取所有条目,在输出中留下一些空白条目。 部分输出如下所示:

数据:教学大纲

数据:

数据:GATE 分数

数据:

数据:GATE 结果

数据:

观察 Gate Score 下面一行中的空白条目,在之前的输出中是 911。

解析器适用于小文件但不适用于大文件 为什么会这样?我正在使用 Python 2.7

【问题讨论】:

  • 尝试使用BeautifulSoup.py 脚本。它在解析 HTML 文件方面做得很好。
  • @Coder 为什么 LibXml 比 BeautifulSoup 好?它是否处理结构不佳的 HTML?它在哪些方面做得更好?
  • 我用过BeautifulSoup,它很好用,很结实。 @Coder,您可能想更新您的链接,因为链接中包含]
  • @Josh Smeaton:lxml 正在快速点亮并且更新更多。甚至BeautifulSoup4 也推荐你安装lxml 并会在可用时使用它。
  • 1) 我用过 BeautifulSoup 和 Lxml,发现 lxml 比 BeautifulSoup 快。 2) Lxml 也可以处理损坏的 html。

标签: python html parsing html-parsing


【解决方案1】:

如果您仔细查看 mediafire 上的 html 页面,您会注意到您有两个包含“GATE Score”的文本块

 line 162: <tr><td class='qlink4' background='webimages/blkbuttona3.jpg' onMouseOut="background='webimages/blkbuttona3.jpg'" onMouseOver="background='webimages/blkbuttonb3.jpg'">&nbsp;<a class="dark2" href="gscore.php" title="GATE Score">GATE Score</a></td></tr>

 line 192: <tr class='trmenu1'><td>GATE Score: </td><td colspan=1>911</td></tr>

您遇到的问题可能是由于您尝试解析的完整 html 页面中的错误,这就是为什么您只能看到一个“GATE 分数”出现。

正如您在 cmets 中所建议的那样,使用更能容忍格式错误的 html 的 BeautifulSoup。

【讨论】:

    【解决方案2】:

    解析 HTML 或 XML 的首选解决方案是 lxmlxpath

    一个关于如何使用xpath的快速而肮脏的例子:

    from lxml import etree
    data = open('result.html','r').read()
    doc = etree.HTML(data)
    
    for tr in doc.xpath('//table/tr[@class="trmenu1"]'):
      print tr.xpath('./td/text()')
    

    产量:

    ['Registration Number: ', ' CS 2047103']
    ['Name of the Candidate: ', 'PATIL SANTOSH KUMARRAO        ']
    ['Examination Paper: ', 'CS - Computer Science and Information Technology']
    ['Marks Obtained: ', '75.67 Out of 100']
    ['GATE Score: ', '911']
    ['All India Rank: ', '34']
    ['No of Candidates Appeared in CS: ', '156780']
    ['Qualifying Marks for CS: ', '\r\n\t\t\t\t\t']
    ['General', 'OBC ', '(Non-Creamy)', 'SC / ST / PD ']
    ['31.54', '28.39', '21.03 ']
    

    这段代码从 HTML 数据中创建了一个ElementTree。使用xpath,它会选择所有具有class="trmenu1" 属性的&lt;tr&gt; 元素。然后对于每个&lt;tr&gt;,它会选择并打印任何&lt;td&gt; 孩子的文本。

    【讨论】:

    • 谢谢,输出正是我想要的。
    • 这根本不能回答问题。
    • @NoémienKocher 4 年前,我为 OP 的问题提供了解决方案,并且 OP 对此感到满意。
    猜你喜欢
    • 1970-01-01
    • 2012-04-13
    • 2016-01-16
    • 2012-09-03
    • 2012-07-12
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    相关资源
    最近更新 更多