1

我正在尝试使用 lxml 库解析网站的源代码以提取其中的文本。这是我的代码

import urllib2
from StringIO import StringIO
from lxml import html
from lxml.html.clean import Cleaner

cleaner = Cleaner(page_structure = False)
htmlsource = cleaner.clean_html(urllib2.urlopen("http://www.verycd.com/").read())
htmltree = html.parse(StringIO(htmlsource.decode("utf-8"))).getroot()
listnode = htmltree.xpath("*")
for node in listnode:
  print node.text_content().strip().encode("utf-8")

当我在交互式控制台中运行代码时,结果如下所示(开发环境)

VeryCD电驴大全 - 分享互联网
用户名:
        密码:记住我 


        免费注册
         |
        忘记密码?



            首页 |
            商城 |
            专题 |
            乐园 |

            社区 |
            电驴 |
            网页游戏 |
            网址大全

但是在生产环境中,所有的unicode字符都显示不正确

VeryCDçµé©´å¤§å¨ - å享äºèç½
ç¨æ·åï¼
        å¯ç ï¼è®°ä½æ 

        Â 
        å费注å
         |
        å¿è®°å¯ç ï¼



            é¦é¡µ |
            åå |
            ä¸é¢ |
            ä¹å |

            ç¤¾åº |
            çµé©´ |
            ç½é¡µæ¸¸æ |
            ç½å大å¨

知道如何解决这个问题吗?

编辑

好像我在这里发现了问题。我认为 Lxml 内置 GAE 有一些问题。如果我在解析 html 之前不使用清洁器,则输出很好。

# cleaner = Cleaner(page_structure = False)
# htmlsource = cleaner.clean_html(urllib2.urlopen("http://www.verycd.com/").read())
htmlsource = urllib2.urlopen("http://www.verycd.com/").read()
htmltree = html.parse(StringIO(htmlsource.decode("utf-8"))).getroot()
4

2 回答 2

1

以下是处理文本的最基本规则:

  1. 阅读后立即将文本解码为 un​​icode(您正在执行此操作)
  2. 用 unicode 进行所有处理(你正在这样做)
  3. 在输出之前对文本进行编码。你没有这样做。

在您的打印语句中添加一个编码,您应该没问题。

于 2012-05-15T23:29:48.363 回答
0

更新此错误已在 App Engine 中修复,因此不再需要以下解决方法。

我已经接受这是 lxml 或 App Engine 中的错误。但是您可以使用lxml.etree.parseand来解决它lxml.etree.HTMLParser(请注意,这lxml.html是对这两者的简单包装):

import urllib2
from StringIO import StringIO
from lxml import etree
from lxml.html.clean import Cleaner

cleaner = Cleaner(page_structure = False)
htmlsource = cleaner.clean_html(urllib2.urlopen("http://www.verycd.com/").read())
htmlparser = etree.HTMLParser(encoding='utf-8')
htmltree = etree.parse(StringIO(htmlsource.decode("utf-8")),
                       parser=htmlparser).getroot()
listnode = htmltree.xpath("*")
for node in listnode:
  print node.text.strip().encode("utf-8")

那是:

  • 创建一个 HTMLParser 对象,显式设置encoding='utf-8'.
  • 使用etree.parse代替html.parse; 传给. parser=htmlparser_etree.parse
  • 使用node.text而不是node.text_content().

这通过明确告诉 HTMLParser 使用 UTF-8 编码而不是让它猜测(它错误地猜测 Latin-1)来解决这个错误。

于 2012-05-17T06:05:21.463 回答