Примечания по сортировке:
Сохранена копия содержимого 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%"> </td>
<td class="verd_black12" width="3%"> </td>
<td class="verd_black12" width="3%"> </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, в котором будет отображаться нужный символ.