2013-03-03 90 views
1

問題的Python/BeautifulSoup解析HTML餾分

  1. 爲什麼是在最後兩情況下,兩個unicode的輸出,但在一種情況下,它顯示了級分,而在另一方面,它顯示了一些其他代碼代表分數?

  2. 什麼是最簡潔的方式讓我從分數到小數(-1.75)?

背景

我使用BeautifulSoupPython閱讀一些HTML.HTML輸出級分。下面是我用來測試這個問題的python代碼和結果輸出。在下面的代碼中,我有

print type(c[0]) 
print c[0] 
print type(c[0].get_text()) 
print c[0].get_text() 
print type(re.split(" ", c[0].get_text())[0]) 
print re.split(" ", c[0].get_text()) 

這種輸出:

<class 'bs4.element.Tag'> 
<b>-1¾ -101</b> 
<type 'unicode'> 
-1¾ -101 
<type 'unicode'> 
[u'-1\xbe\xa0-101'] 

回答

2

讓我們你的問題的最簡單的部分出的第一方式:

當打印清單時,repr的內容用於表示列表中的項目。如此以來,

re.split(" ", c[0].get_text()) 

是一個列表,打印語句打印在列表中unicode元素的repr

In [63]: x = u'-1\xbe\xa0-101' 

In [64]: print(x) 
-1¾ -101 

In [65]: repr(x) 
Out[65]: "u'-1\\xbe\\xa0-101'" 

現在到了有趣的部分:一些Unicode代碼點有名字。 例如,

In [60]: import unicodedata as ud 

In [61]: ud.name(u'\xbe') 
Out[61]: 'VULGAR FRACTION THREE QUARTERS' 

其實,我們可以通過所有那些匹配的模式'FRACTION (\w+) (\w+)'其名稱中的Unicode字符搜索:

import unicodedata as ud 
import re 

numerator = { 
    'ONE':1, 
    'TWO':2, 
    'THREE':3, 
    'FOUR':4, 
    'FIVE':5, 
    'SIX':6, 
    'SEVEN':7, 
    'EIGHT':8, 
    'NINE':9, 
    'ZERO':0, 
    } 

denominator = { 
    'QUARTER':4, 
    'HALF':2, 
    'SEVENTH':7, 
    'NINTH':9, 
    'THIRD':3, 
    'FIFTH':5, 
    'SIXTH':6, 
    'EIGHTH':8, 
    'SIXTEENTH':16 
    } 

fraction = {} 
for num in range(0x110000): 
    s = unichr(num) 
    try: 
     name = ud.name(s) 
    except ValueError: 
     continue 
    match = re.search('FRACTION ({n}) ({d})'.format(
     n = '|'.join(numerator.keys()), 
     d = '|'.join(denominator.keys()), 
     ) , name) 
    if match: 
     fraction[num] = unicode(
      float(numerator[match.group(1)])/denominator[match.group(2)]).lstrip('0') 
print(fraction) 

因此,我們現在有一個dict名爲fraction它映射的Unicode代碼指向unicode分數的十進制表示。

{8585: u'.0', 43056: u'.25', 43057: u'.5', 43058: u'.75', 43059: u'.0625', 43060: u'.125', 43061: u'.1875', 188: u'.25', 189: u'.5', 190: u'.75', 8528: u'.142857142857', 8529: u'.111111111111', 8531: u'.333333333333', 8532: u'.666666666667', 8533: u'.2', 8534: u'.4', 8535: u'.6', 8536: u'.8', 8537: u'.166666666667', 8538: u'.833333333333', 8539: u'.125', 8540: u'.375', 8541: u'.625', 8542: u'.875', 69245: u'.333333333333', 3443: u'.25', 3444: u'.5', 3445: u'.75', 69243: u'.5', 69244: u'.25', 11517: u'.5', 69246: u'.666666666667'} 

現在你可以翻譯u'-1\xbe\xa0-101'這樣的:

text = u'-1\xbe\xa0-101' 
print(text.translate(fraction))  

產生

-1.75 -101 

那麼簡單的答案是:

fraction = {8585: u'.0', 43056: u'.25', 43057: u'.5', 43058: u'.75', 43059: u'.0625', 43060: u'.125', 43061: u'.1875', 188: u'.25', 189: u'.5', 190: u'.75', 8528: u'.142857142857', 8529: u'.111111111111', 8531: u'.333333333333', 8532: u'.666666666667', 8533: u'.2', 8534: u'.4', 8535: u'.6', 8536: u'.8', 8537: u'.166666666667', 8538: u'.833333333333', 8539: u'.125', 8540: u'.375', 8541: u'.625', 8542: u'.875', 69245: u'.333333333333', 3443: u'.25', 3444: u'.5', 3445: u'.75', 69243: u'.5', 69244: u'.25', 11517: u'.5', 69246: u'.666666666667'} 
text = c[0].get_text() 
text = text.translate(fraction) 
parts = map(float, text.split()) 
print(parts) 

產量

[-1.75, -101.0] 

注意,在將來很可能更多的分數分配的Unicode碼點。也可能unicode代碼點的名稱與我用於生成fraction字典的'FRACTION ({n}) ({d})'模式不匹配。所以我的解決方案有點脆弱,未來可能需要更新。

+0

unutbu非常感謝回覆。我很驚訝沒有一個圖書館或者已經爲這個問題創建了一些東西。我只是n00bie程序員,所以它花了我一段時間來通過你的答案,這是很酷,我從你的編程技術這裏學習。 – appleLover 2013-03-04 02:05:52

+0

如果您有任何問題,我會盡力詳細說明。 – unutbu 2013-03-04 02:12:53