почему так много строк данных не могут получить? - PullRequest
0 голосов
/ 19 января 2012

Мой код:

import urllib
import lxml.html
equitydown="http://sc.hkex.com.hk/gb/www.hkex.com.hk/chi/market/sec_tradinfo/stockcode/eisdeqty_c.htm"   
file=urllib.urlopen(equitydown).read()   
root=lxml.html.document_fromstring(file) 
rdata = root.xpath('//tr[@class="tr_normal" and (.//img)]')
for data in rdata:
    data.getparent().remove(data)
for code in root.xpath('//tr[@class="tr_normal"]/td[position()=1]'):
    print code

вы можете увидеть вывод, (пропущено много)

00320
00321
00322
00323
00325
00326
00327
00328

, но когда вы открываете Hong Kong Exchanges and Clearing Limited , вы получаете много строк, например (пропущено много):

06830 华众控股 2,000 #  
06838 盈利时 2,000 #  
06868 天福 1,000 #    
06880 豪特保健 2,000 #   
06883 新濠博亚娱乐 300 #   

Я теряю много кодов: 06830 06838 06868 06880 06883 (опущено много), код которых стоит за 00329, все они потеряны.

Я не понимаю весь код, почему?


import urllib
import lxml.html
equitydown="http://sc.hkex.com.hk/gb/www.hkex.com.hk/chi/market/sec_tradinfo/stockcode/eisdeqty_c.htm"   
file=urllib.urlopen(equitydown).read()   
root=lxml.html.document_fromstring(file) 
for code in root.xpath('//tr[@class="tr_normal" and not(.//img)]/td[position()=1]'):
    print code.text_content()

он по-прежнему получает неправильный вывод, пожалуйста, попробуйте запустить его, чтобы увидеть, что происходит? код за 00328 не может получить, в чем причина?

Ответы [ 2 ]

2 голосов
/ 21 января 2012

Примечания по сортировке:

Сохранена копия содержимого URL в файл на случай, если это движущаяся цель.

Бросил ее в W3C-валидатор HTML ...результат был:

Извините, я не могу проверить этот документ, поскольку в строке 18 он содержал один или несколько байтов, которые я не могу интерпретировать как gb2312 (другими словами, найденные байты не являются допустимыми значениями вуказанная кодировка символов).Пожалуйста, проверьте как содержимое файла, так и указание кодировки символов.

Ошибка: euc-cn "\ xFA" не соответствует Unicode

В сторону: Есть ложь, проклятая ложь, и декларации кодирования, которые ссылаются на iso-8859-1 или gb2312.

Попытка content.decode('gb2312', она не удалась.

 >>> guff = open('lxml_hke_raw.htm', 'rb').read()
 >>> len(guff) 715608
 >>> guff.decode('gb2312') Traceback (most recent call last):
 File "<stdin>", line 1, in <module> UnicodeDecodeError: 'gb2312' codec can't
 decode bytes in position 171039-171040: illegal multibyte sequence
 >>> pos=171039
 >>> guff[pos:pos+2]
 '\xfa\xe2'

Исследование вокруг позиции сбоя дало следующее (вручнуюотступ, многие нерелевантные атрибуты удалены или сокращены):

<tr class="tr_normal">
    <td class="verd_black12" width="18%">00329</td>
    <td class="verd_black12" width="42%">
        <a 
            href="http://sc.hkex.com.hk/etc/etc/etc"
            target="_parent"
        >
            <img
                src="http://sc.hkex.com.hk:80/fs?FAE2+5+13+004B96"
                alt="\xfa\xe2"  #### not a valid gb2312 sequence ####
            > #### also the "img" element is not terminated ####
        \xc1\xfa\xb9\xfa\xbc\xca
        </a>
    </td>
    <td class="verd_black12" width="19%">10,000</td>
    <td class="verd_black12" width="3%" align="center">#</td>
    <td class="verd_black12" width="3%">&nbsp;</td>
    <td class="verd_black12" width="3%">&nbsp;</td>
    <td class="verd_black12" width="3%">&nbsp;</td>
</tr>

Это указывает, почему он остановился на элементе, содержащем 00329.Обратите внимание, что есть еще один случай этого в файле.

Kludge:

ucontent = content.decode('gb2312', 'replace')
repchar = u'\uFFFD'
print ucontent.count(repchar) # 2
ucontent2 = ucontent.replace(repchar, '[NON-GB2312 SEQUENCE]')
content2 = ucontent2.encode('gb2312')

Это может быть записано в новый файл или проанализировано:

root = lxml.html.document_fromstring(content2) 
for el in root.iter('tr'):
    if el.get('class') != 'tr_normal': continue
    print all(ch.tag == 'td' for ch in el), [ch.text for ch in el]

Сокращенный вывод:

True ['00001', None, '1,000', '#', 'H', 'O', 'F']
True ['00002', None, '500', '#', 'H', 'O', 'F']
...
True ['00328', None, '2,000', '#', u'\xa0', u'\xa0', u'\xa0']
True ['00329', None, '10,000', '#', u'\xa0', u'\xa0', u'\xa0']
True ['00330', None, '100', '#', 'H', 'O', 'F']
...
True ['06880', None, '2,000', '#', u'\xa0', u'\xa0', u'\xa0']
True ['06883', None, '300', '#', u'\xa0', u'\xa0', u'\xa0']

Еще одна загадка:

Исходный контент в порядке с Python 2.7.2 декодируется с gb18030.Однако изменение кодировки в файле не сработало (не выводится после 00329).Также попытки переопределить кодировку с использованием lxml encoding arg дали тот же эффект.

Замечание: нарушающее \xfa\xe2 декодируется с gb18030 до u'\ue331', которое находится в BMP Private UseОбласть , которая учитывает элемент img, который предоставляет URL-адрес для GIF, в котором будет отображаться нужный символ.

0 голосов
/ 19 января 2012

Обратите внимание, что 00329 является первым с img, поэтому я считаю, что ваша remove является проблемой.Возможно, он испортил итератор xpath, попробуйте сначала преобразовать его в list.

Или попробуйте:

root=lxml.html.document_fromstring(file)
for code in root.xpath('//tr[@class="tr_normal" and not(.//img)]/td[position()=1]'):
  print code
...