1

lxmlライブラリを使用して、Webサイトのソースを解析し、内部のテキストを抽出しようとしています。これが私のコードです

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. あなたがそれを読んだらすぐにテキストをユニコードにデコードします(あなたはこれをやっています)
  2. すべての処理をUnicodeで実行します(これを実行しています)
  3. 出力の直前にテキストをエンコードします。あなたはこれをしていません。

印刷ステートメントにエンコードを追加すると、問題がないはずです。

于 2012-05-15T23:29:48.363 に答える
0

更新このバグはApp Engineで修正されているため、次の回避策は不要になります。

これをlxmlまたはAppEngineのバグとして受け入れました。lxml.etree.parseただし、andを使用して回避できます(これは、これら2つの単純なラッパーである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 に答える