2011-12-15 8 views
0

正規表現はbeautifulsoupを扱う貧しい人のアプローチですが、htmlによく定義されているタグが解析されない場合は、私の唯一の選択肢かどうか疑問に思っていましたか?Beautifulsoupタグが悪いタグを解析する

私は最終的にはちょうどHTMLからいくつかの単純なデータを取得しようとしている...しかし、それだけでこのように見える一連のテーブルにあります:

<table width="733" border="0" cellpadding="2"> 
<tr> 
<td align="right" valign="top" nowrap="nowrap" bgcolor="#29ff36"> 
<font size="-1" face="Verdana, Arial, Helvetica, sans-serif"> 
<strong> 
PART CODE: 
</strong> 
</font> 
</td> 
<td align="left" valign="top" nowrap="nowrap"> 
<font size="-1" color="#7b1010" face="Verdana, Arial, Helvetica, sans-serif"> 
PART# (//THIS IS WHAT I WANT) 
</font> 
</td> 
<td> 
</td> 

はなく、これをアプローチする良い方法はあります正規表現?

助けを借りてくれてありがとう。このサイトでは、信じられないほどの

OKです:

、約15これらのテーブルのありますそれぞれが最初のセルに座っている(例えばオンハンドコスト、ベンダー、など)のラベルを持ち、その後、実際にIデータ常に次のセルに欲しいです。それにラベルを持つ正しいセルを見つけることが十分に機能

label = 'Price:' 
rows = soup.findAll('tr') 
for tr in rows: 
    cols = tr.findAll('td') 
    for td in cols: 
    if td.find(text=True) == label: 
     print td.find(text=True) 

...私は基本的にはちょうど今、私は推測する上で次のセルを見つける必要があります。 beautifulsoupのドキュメントごとの "次の"コマンドは実際にはこれを達成していません。 考えていますか?

+1

はい、あなたは 'BeautifulSoup'を使うことができます。しかし、私はそれがあなたが望む答えだとは思わない。少し質問を明確にすることはできますか? –

+0

あなたが望むデータはユニークですか?それは常にテーブルの最初の行の2番目のセルにありますか?テキストは毎回特定のテキストで始まっていますか? BeautifulSoupやその他のHTMLパーサーに、そのような情報なしに抽出するデータを指定する方法はありません。 – Acorn

+0

BeautifulSoupでは、数行のコードでテーブルのセットと各テーブルの行セットを取得できます。 「パート#(私はこれが何を望んでいるか)」を取得するのもかなり簡単です。問題の原因となるサンプルを提供してください。 – Kirill

答えて

0

あなたが提供した例は必ずしも明らかではありませんが、ここではあなたの例のHTMLソースから部品番号を取得するスニペットがあります:

columns = soup.findAll('td') 
for col in columns: 
    try: 
     part = col.find("font", {"color": "#7b1010"}).contents[0] 
     print(part) 
    except: 
     pass 
+0

これは素晴らしいです。ありがとうございました –

+0

私はちょうどリストにこれを格納し、標準的なリストからデータをプルアップする - ちょっとした問題は、毎回テーブルの数が違うということです。 、時にはそれは一部です[9] 私は具体的に "PART CODE:"を探してこのコードを実行する方法はありますか? この検索方法のヒント –

+0

@Jen Scottこのトリックは、正しく解析するために必要なすべてのデータを含むページの最小のパーティションを特定することです。 この場合、trのページでsoup.findAll()を実行してから、各trのrows.findAll()を実行して列を取得することをお勧めします。 PART CODEとPART#の両方が並んでいる場合は、データを保存することがわかります。 – Condiment

-1

lxmlの人々は不正な形式のHTMLでうまく動作すると主張しています。

2

beautifulsoupの代わりにlxmlとすることもできます。 cssselect()メソッドのため、beautifulsoupの代わりにlxml.htmlを使用するように切り替えました。 cssファイルやjQueryで使用するのと同じようにCSSルールが必要です。

from lxml.html import fromstring 

raw_html_data = """ ... your html data here ... """ 

doc = fromstring(raw_html_data) 
part_number = doc.cssselect('td[align=left] font')[0].text 
# part_number.strip() # optionally strip leading and trailing whitespace 

lxmlをインストールするにはpipを使用できます。

$ pip install lxml 

シルバープラッターソリューション:

# ... starting with doc from above 
info = [] 
target_trs = doc.cssselect('table tr') # tweak based on actual html 
for tr in trs: 
    target_cells = tr.cssselect('td font') 
    label = target_cells[0].text.strip() 
    data = target_cells[1].text.strip() 
    info.append((label,data)) 
# now you have an array of (label,data) pairs in info 
+0

これは機能しません。私は推測trsはtarget_trsになっていると思うが、私はまだ属性のエラーを取得しています:非タイプのオブジェクトは、これを実行する属性 'ストリップ'がありません。 –

+0

うん、typo ... s/target-trs/trs /。これをコンソール(Pythonコンソールまたはjavascriptのブラウザコンソール)で再生して、正しく取得します。あなたは本当にこのようなもので遊ぶ必要があり、あなたはbeautifulsoupかlxmlのいずれかを使って物事を理解するために必要なものすべてを学ぶでしょう。 NoneTypeの問題は、HTMLが100%一貫してフォーマットされていないか、他のものを使用して最終的なターゲットセルを選択する必要があるように聞こえるように聞こえます。小さなHTMLスニペットでもう一度テストして、動作していることを確認してから、ページ全体のHTMLでテストしてください。がんばろう。 – istruble