使用minidom获取指定<table>中的HTML链接

1 投票
2 回答
2900 浏览
提问于 2025-04-15 17:56

我想用Python和xml.dom.minidom来获取一个特定的

里的链接,这个
是通过它的ID来指定的。根据一些很棒的建议,我打算使用DOM而不是模式匹配。

import urllib
import xml.dom.minidom

url = 'http://www.batstrading.com/market_data/shortsales'
page = xml.dom.minidom.parse(urllib.urlopen(url))

我可以通过标签名page.getElementsByTagName('a')获取所有的链接,但我无法限制只获取ID为“monthly-short-sale”的表格内的链接。使用getElementById返回的是None。

这是不是因为“monthly-short-sale”这个ID在DTD中没有定义?如果是的话,提取这些信息的最佳方法是什么?

这是我目前使用的代码,它能工作,但有点不太规范:

import urllib
import xml.dom.minidom
import datetime

url = 'http://www.batstrading.com/market_data/shortsales'

def getDownloadLink(alink, prefix = 'BATSsh'):
    """return (datetime.date, link) for the provided link if the link
    target starts with the data file prefix"""

    n = len(prefix)
    href = alink.getAttribute('href')
    if href.startswith(prefix) and (len(href) == 25):
        year = int(href[n:n+4])
        month = int(href[n+4:n+6])
        day = int(href[n+6:n+8])
        date = datetime.date(year, month, day)
        return (date, url + '/' + href)

page = xml.dom.minidom.parse(urllib.urlopen(url))
link = (getDownloadLink(a) for a in page.getElementsByTagName('a'))
link = dict(i for i in link if i is not None)

2 个回答

0

我觉得你首先应该找到那个TABLE元素,然后在它上面调用getElemenetByTagName方法。这样应该能返回所有作为TABLE元素子元素的a元素。另外,记得检查一下你的HTML是不是XHTML格式,因为minidom是用来解析XML的,不是HTML。

4

问题在于,minidom 是一个不读取外部实体的 XML 解析器。这意味着它根本不看 DTD(文档类型定义),所以它不知道在 HTML 中,名为 id 的属性对应于 ID 的模式类型。

这还带来了一个后果,就是 minidom 不会识别像 &eacute; 这样的 HTML 特定实体,这些实体是在 XHTML 文档类型中定义的,所以你可能会因此丢失一些文本。

如果你对此不在意,可以继续使用 minidom,并通过其他方式获取表格,比如使用 getElementsByTagName 方法,然后手动检查 element.id。你也可以自己写一个 getElementById 函数来慢慢实现这个功能。

或者,你可以使用一个允许外部实体的 XML 解析器,比如 pxdom。不过这样的话,解析器每次都需要从 W3 获取并解析 DTD,这样会非常慢。

另外,你也可以选择一个 HTML 解析器,比如 BeautifulSoup,它内置了 HTML 实体和 ID 的处理。这在处理真实的 HTML 页面时可能是个更好的选择,因为这些页面虽然可能声称是 XHTML,但实际上常常包含一些格式不规范的内容。

撰写回答