【问题标题】:python3 How do I identify / handle unwanted unicode from scraped web page?python3 如何从抓取的网页中识别/处理不需要的 unicode?
【发布时间】:2014-08-05 19:49:45
【问题描述】:

我无法理解一些 unicode,我是从用户通过 Web 表单填充的网页中抓取的。最后,我想使用 NLTK 对抓取的文本进行标记和处理,但是不需要的字符会阻碍。我无法弄清楚如何删除这些。

我首先使用 selenium webdriver 来获取网页、提取文本内容并打印到文件:

driver.get(URL)
HTML = driver.page_source
soup = bs(HTML) [s.extract()
[s.extract() for s in soup(['style', 'script', '[document]', 'head', 'title'])]
text = soup.getText()
outFile.write(text)
outFile.close()

(nmgeek 推荐了 s.extract() 推导,然后是 soup.getText() in response to a different stackoverflow posting。)当我使用“cat ”时,生成的文件看起来不错,但将特殊字符显示为项目符号、•、® 和 ™,结果证明这是有问题的。 (毫无疑问还有其他人。)

首先,当我尝试在打印到原始 outFile 之前删除这些项目符号时,使用

clean = re.sub(r'•', r'', text)
outFile.write(clean)

我没有成功;子弹还在。

其次,我阅读了为使用 NLTK 进行后处理而生成的 。使用

raw = open(textFile).read() 令牌 = nltk.word_tokenize(raw)

项目符号显示在原始字符串中,并在 word_tokenize() 步骤之后保留为不需要的标记。如果我打印令牌,这些代码点 (?) 将显示为“�\x80�”。

我尝试使用对表单的理解来删除项目符号

words = [w.lower() for w in nltk.Text(tokens) \
         if w.lower() not in ['•', '®', '™']]

但特殊字符仍然存在。

我怀疑转换为字节是解决这个问题的方法,但也许这些信息中有一些有用的东西。 (但是,请参阅下面的解决方案/解决方法。)当我将这些编码为 utf-8 和 latin-1 时,结果是:

In [8]: '�\x80�'.encode('utf-8')
Out[8]: b'\xc3\xaf\xc2\xbf\xc2\xbd\xc2\x80\xc3\xaf\xc2\xbf\xc2\xbd'
In [9]: '�\x80�'.encode('latin-1')
Out[9]: b'\xef\xbf\xbd\x80\xef\xbf\xbd'

只是粘贴在文本文件中找到的项目符号,我得到了这些字节表示:

In [10]: '•'.encode('utf-8')
Out[10]: b'\xc3\xa2\xc2\x80\xc2\xa2'
In [11]: '•'.encode('latin-1')
Out[11]: b'\xe2\x80\xa2'

Python 的 repr() 函数似乎没有提供任何明确性:

In [35]: repr(tokens[303:309])
Out[35]: "['�\\x80�', 'Wealth', 'of', 'outdoor', 'recreational', 'activities']"

我已经通过Python 3 Unicode Howto 几次,但无法弄清楚如何理解这些组合信息。

【问题讨论】:

  • 如果您发布repr(text),或者至少其中包含有问题的字符的部分,它可能会提供一些额外的清晰度。这将准确地告诉我们您正在处理的字节或字符串。
  • 在原始帖子底部附近添加了示例。
  • 这真的很奇怪。我希望 repr 返回一个可打印字符的 str,而不是其中包含 s 的一个。
  • 编码问题是 Python 的常见问题,尤其是在 Windows 上运行时。两个建议: 1)先试试看在charset下的网页头部是否有提到的编码 - 它会告诉你如何解码内容; 2)如果您确定编码,请始终使用 decode - 例如raw.decode('utf-8', 'ignore') - 注意:不是编码而是解码。最后,如果您确定它是 utf-8 并且想要处理那些清晰易读的 Unicode 符号,最好使用 unidecode 模块将它们尽可能地转换为 ASCII。如果抓取非英文网页,必须帮助不要损失太多。
  • @Everst 以防万一这澄清了事情,我在 linux 下运行。我在原始网页上看不到编码信息。 (但是,如果用户将内容从他们的 Word 应用程序粘贴到文本框中,这是否重要?)我得到“'str' object has no attribute 'decode'”,这让我想知道你是否正在处理这些作为 Python 2.x 字符串(?)......我会看看我能不能用 unidecode 做点什么。

标签: selenium python-3.x unicode beautifulsoup nltk


【解决方案1】:

将原始文本标记为丑陋令牌后,我使用以下方法删除了违规字符:

tokens = [t for t in uglyTokens if t.encode('utf-8') not in \
          [b'\xc3\xa2\xc2\x80\xc2\xa2', \
           b'\xc3\xa2\xc2\x80\xc2\x99']]

我通过列出丑陋的令牌,识别不受欢迎的示例,然后使用来找到合适的字节形式

In [21]: uglyTokens[2841].encode('utf-8')
Out[21]:b'\xc3\xa2\xc2\x80\xc2\xa2'

注意这种情况匹配

'•'.encode('utf-8')

在原始帖子中。

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多