LXML.HTML5PARSER:不适用于阿拉伯语/波斯语HTML5



我正在使用LXML的HTML5PARSERASCII字符还可以,但是如果我下载了其中包含波斯语和俄罗斯字符的HTML文件,则会出现此错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 418: ordinal not in range(128)

这是响应文本:http://paste.ubuntu.com/23552349/

这是我的代码(如您所见,我仅删除了所有非有效XML字符):

f = requests.post('http://www.example.com/getHtml.php?', headers=headers, cookies=cookies, data=data)
resp = f.text
if resp == "":
    return []
resp = encode("utf-8")
resp = ''.join(c for c in resp if valid_xml_char_ordinal(c))
doc = html5parser.fragment_fromstring(resp.encode("utf-8"), guess_charset=False, create_parent='div')
  • 如果我删除了行:reves = encode(" utf-8")此错误将出现:

    value error:所有字符串必须兼容:unicode或ascii,无null字节或控制字符

直接使用html5parser时,我也会遇到一些奇怪的矛盾( TypeError: __init__() got an unexpected keyword argument 'useChardet'及其类似的东西)。

如果您已经安装了LXML,那么使用Beautifulsoup包装器很高兴。

首先安装BeautifulSoup(pip install beautifulsoup4)。然后:

import requests
from bs4 import BeautifulSoup
# (initialize headers, cookies and data)
f = requests.post('http://www.example.com/getHtml.php?', headers=headers, cookies=cookies, data=data)
resp = f.text
if not resp:
    return []
doc = BeautifulSoup(resp, 'lxml')

然后,您可以使用美丽的套件清洁API来操纵HTML树。在引擎盖下,它仍然使用LXML进行解析。

ref for Beautifulsoup api:https://www.crummy.com/software/beautifulsoup/bs4/doc/

resp = ''.join(c for c in resp if valid_xml_char_ordinal(c))

这种试图过滤不良字符的尝试不起作用,因为输入中的控制字符实际上被编码为数字字符引用,而不是原始字符:

<td class="artistFlux">السيف النشيد الدولة الإسلامية التي من شأن&#16</td>

特别是 &#16(在此处由左转的文本遮盖)。诸如U 0010(16)之类的控制字符在HTML5中也无效,即使是字符参考。

最好如果您可以修复产生此cruff的上游脚本,但是如果您必须从输入中删除类似的bum字符引用,则可以执行另一个过滤器来删除诸如 &#(3[01]|2[0-9]|1[124-9]|[0-8]])(?=[^0-9])的正则频率。

顺便说一句,您不需要正常编码和解码而乱七八糟。您可以读取f.content响应的原始字节并直接馈送到HTML5Parser,以避免解码对text的响应,然后将其重新编码为字节。您可能还需要fragments_fromstring复数,因为您的输入中有两个顶级元素。

最新更新