2016-07-21 28 views
2

私はBeutifulsoup 4とPython 3.5+を使用してWebデータを抽出しています。Beautifulsoupで、指定した以外の要素のタグを抽出

<div class="the-one-i-want"> 
    <p> 
     content 
    </p> 
    <p> 
     content 
    </p> 
    <p> 
     content 
    </p> 
    <p> 
     content 
    </p> 
    <ol> 
     <li> 
      list item 
     </li> 
     <li> 
      list item 
     </li> 
    </ol> 
    <div class='something-i-don't-want> 
     content 
    </div> 
    <script class="something-else-i-dont-want'> 
     script 
    </script> 
    <p> 
     content 
    </p> 
</div> 

私は<div class="the-one-i-want">要素内に発見された抽出したいコンテンツのすべてを:私は解凍していたから、次のHTMLを、持っています。今、私はほとんどの時間を仕事、次の方法、使用しています:

soup = Beautifulsoup(html.text, 'lxml') 
content = soup.find('div', class_='the-one-i-want').findAll('p') 

をこれは、スクリプト、奇妙な挿入div除外年代や、広告などそれ以外の非予測可能なコンテンツをまたは 『コンテンツ』タイプのものをお勧めします。

ここでは、<p>タグ以外の要素があり、リストのようにメインコンテンツに対して文脈上重要なコンテンツを持つ場合があります。

のような方法で、<div class="the-one-i-want">からコンテンツを取得する方法があります:

soup = Beautifulsoup(html.text, 'lxml') 
content = soup.find('div', class_='the-one-i-want').findAll(desired-content-elements) 

desired-content-elements私はその特定のコンテンツのためのフィット感とみなさすべての要素を含むだろうか?例えば、<p>タグ、すべて<ol>タグ、<li>タグなどがありますが、<div>または<script>タグはありません。私は単に別の反復プロセスを通じて異なる要素タイプを発見した場合は管理が困難証明することになる、発生順に

content_string = '' 
for p in content: 
    content_string += str(p) 

このアプローチは、データを収集します。おそらく、注目に値する

は、コンテンツを保存する私の方法であり、 。可能であれば、各要素が元々コンテンツ内で発生した順序を再アセンブルするために分割リストの再構築を管理する必要はありません。

答えて

1

あなたがしたいタグのリストを渡すことができます。

content = soup.find('div', class_='the-one-i-want').find_all(["p", "ol", "whatever"]) 

我々はpとの事前のタグを探しているあなたの質問のURLに似た何かを実行する場合、あなたは私たちが両方を見ることができます:

...: for ele in soup.select_one("td.postcell").find_all(["pre","p"]): 
    ...:  print(ele) 
    ...: 

<p>I'm using Beutifulsoup 4 and Python 3.5+ to extract webdata. I have the following html, from which I am extracting:</p> 
<pre><code>&lt;div class="the-one-i-want"&gt; 
    &lt;p&gt; 
     content 
    &lt;/p&gt; 
    &lt;p&gt; 
     content 
    &lt;/p&gt; 
    &lt;p&gt; 
     content 
    &lt;/p&gt; 
    &lt;p&gt; 
     content 
    &lt;/p&gt; 
    &lt;ol&gt; 
     &lt;li&gt; 
      list item 
     &lt;/li&gt; 
     &lt;li&gt; 
      list item 
     &lt;/li&gt; 
    &lt;/ol&gt; 
    &lt;div class='something-i-don't-want&gt; 
     content 
    &lt;/div&gt; 
    &lt;script class="something-else-i-dont-want'&gt; 
     script 
    &lt;/script&gt; 
    &lt;p&gt; 
     content 
    &lt;/p&gt; 
&lt;/div&gt; 
</code></pre> 
<p>All of the content that I want to extract is found within the <code>&lt;div class="the-one-i-want"&gt;</code> element. Right now, I'm using the following methods, which work most of the time:</p> 
<pre><code>soup = Beautifulsoup(html.text, 'lxml') 
content = soup.find('div', class_='the-one-i-want').findAll('p') 
</code></pre> 
<p>This excludes scripts, weird insert <code>div</code>'s and otherwise un-predictable content such as ads or 'recommended content' type stuff.</p> 
<p>Now, there are some instances in which there are elements other than just the <code>&lt;p&gt;</code> tags, which has content that is contextually important to the main content, such as lists.</p> 
<p>Is there a way to get the content from the <code>&lt;div class="the-one-i-want"&gt;</code> in a manner as such:</p> 
<pre><code>soup = Beautifulsoup(html.text, 'lxml') 
content = soup.find('div', class_='the-one-i-want').findAll(desired-content-elements) 
</code></pre> 
<p>Where <code>desired-content-elements</code>would be inclusive of every element that I deemed fit for that particular content? Such as, all <code>&lt;p&gt;</code> tags, all <code>&lt;ol&gt;</code> and <code>&lt;li&gt;</code> tags, but no <code>&lt;div&gt;</code> or <code>&lt;script&gt;</code> tags.</p> 
<p>Perhaps noteworthy, is my method of saving the content:</p> 
<pre><code>content_string = '' 
for p in content: 
    content_string += str(p) 
</code></pre> 
<p>This approach collects the data, in order of occurrence, which would prove difficult to manage if I simply found different element types through different iteration processes. I'm looking to NOT have to manage re-construction of split lists to re-assemble the order in which each element originally occurred in the content, if possible.</p> 
+0

魅力のように動作します、ご協力ありがとうございます@パレード – theeastcoastwest

-1

これは機能しますか? divタグとscriptタグを無視しながら、必要なテキストを追加してコンテンツをループする必要があります。

for p in content: 
    if p.find('div') or p.find('script'): 
     continue 
    content_string += str(p) 
0

あなたは非常に簡単に使用してそれを行うことができます

soup = Beautifulsoup(html.text, 'lxml') 
desired-tags = {'div', 'ol'} # add what you need 
content = filter(lambda x: x.name in desired-tags 
     soup.find('div', class_='the-one-i-want').children) 

これはすべてdivタグの子を経由します。これが再帰的に起こるようにしたい場合は(liタグを追加することについて)、.childrenの代わりに.decendantsを使用する必要があります。ハッピークロール!

関連する問題