Получить HTML-ссылки в пределах указанного <table>, используя minidom - PullRequest
1 голос
/ 12 января 2010

Я хочу использовать Python и xml.dom.minidom, чтобы получить список ссылок в определенном <table>, указанном идентификатором таблицы. Основываясь на некоторых превосходных советах , я пытаюсь использовать 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'), но не могу ограничить ссылки, возвращаемые только ссылками, содержащимися в таблице с идентификатором «month-short-sale». Использование getElementById возвращает None.

Это из-за того, что идентификатор "ежемесячная короткая продажа" не определен в 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 ]

4 голосов
/ 12 января 2010

Проблема в том, что minidom - это синтаксический анализатор не для чтения внешних объектов. Это означает, что он даже не смотрит на DTD, поэтому он не знает, что в HTML атрибут с именем id соответствует типу схемы ID.

Еще одним следствием этого является то, что minidom не будет знать о специфических для HTML сущностях, таких как &eacute;, которые определены в типе XHTML, поэтому вы можете потерять текст таким образом.

Если вас это не волнует, вы можете продолжить использовать minidom и использовать альтернативный способ добраться до стола, включающий getElementsByTagName и проверку element.id вручную. (Вы можете взломать свою собственную функцию getElementById, чтобы сделать это медленным способом.)

Или вы можете использовать синтаксический анализатор XML, который разрешает внешние объекты, такие как pxdom. Однако это означает, что синтаксический анализатор должен будет каждый раз получать и анализировать DTD из W3, что будет неприятно медленным.

Или вы можете использовать синтаксический анализатор HTML, в котором есть встроенные сущности HTML и идентификаторы ID, например BeautifulSoup. Это может быть лучшей идеей, когда вы имеете дело с реальными HTML-страницами, которые обозначаются как text/html, хотя они могут претендовать на звание XHTML и часто содержат непослушные фрагменты, которые плохо сформированы.

0 голосов
/ 12 января 2010

Я думаю, что вы хотите сначала найти элемент TABLE, а затем вызвать getElemenetByTagName для него. Это должно вернуть все элементы a , которые являются дочерними элементами элемента таблицы. Кроме того, дважды проверьте, что ваш HTML является XHTML; minidom предназначен для анализа XML, а не HTML.

...