2011-01-05 9 views
1

urllib.request python3.1を使用してHTMLファイルからソースコードを抽出次のコードを実装することで、私はhtmlファイルから正規表現を使用してデータを取得しようとしている

File "extract.py", line 33, in extract_words 
match = re.findall("<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text) 
File "/usr/lib/python3.1/re.py", line 192, in findall 
return _compile(pattern, flags).findall(string) 
TypeError: can't use a string pattern on a bytes-like object 

さらにIDLEで実験したところ、uf.read()は最初に呼び出すときに実際にHTMLソースコードを返すことに気付きました。しかしそれ以降、a-b ''が返されます。これを回避する方法はありますか?

答えて

2

uf.read()は内容を一度だけ読み込みます。それからあなたはそれを閉じてもう一度それを読むためにそれを開く必要があります。これはあらゆる種類のストリームに当てはまります。しかしこれは問題ではありません。

問題は、ファイルやWebページなどの任意の種類のバイナリソースから読み取ると、エンコードを指定しない限り、bytesタイプのデータが返されることです。しかし、あなたの正規表現はbytesタイプとして指定されておらず、ユニコードstrとして指定されています。

モジュールreモジュールは、バイトデータに対してユニコードパターンを使用することをかなり合理的に拒否します。

解決策は、正規表現パターンをバイト文字列にすることです。これを行うには、文字列の前にbを付けることです。したがって:

match = re.findall(b"<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text) 

別のオプションは、それはまた、ユニコードstrあるので、テキストをデコードすることです:

encoding = uf.headers.getparam('charset') 
text = text.decode(encoding) 
match = re.findall("<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text) 

(また、HTMLからデータを抽出するために、私はlxmlがより良い選択肢であると言うでしょう)。

関連する問題