2017-02-04 12 views
0

私はBeautifulSoupをプロジェクトに使用しています。ここでBeautifulSoup入れ子クラスセレクタ

<div class="container"> 
<div class="fruits"> 
    <div class="apple"> 
     <p>John</p> 
     <p>Sam</p> 
     <p>Bailey</p> 
     <p>Jack</p> 
     <ul> 
      <li>Sour</li> 
      <li>Sweet</li> 
      <li>Salty</li> 
     </ul> 
     <span>Fruits are good</span> 
    </div> 
    <div class="mango"> 
     <p>Randy</p> 
     <p>James</p> 
    </div> 
</div> 
<div class="apple"> 
    <p>Bill</p> 
    <p>Sean</p> 
</div> 
</div> 

は今、私はクラス該当のdivクラス「りんご」にテキストをつかむしたい私のHTML構造である「果物」

これは私がこれまで試してみましたものです... 。

for node in soup.find_all("div", class_="apple") 

そのは...戻っ

  • ビル
  • ショーン

しかし、私はそれだけで返すようにしたい...

  • ジョン
  • サム
  • ベイリー
  • ジャック
  • サワー
  • スウィート
  • 塩辛い
  • 果物は

良いです、私は=「りんご」そのクラス内の異なるHTML要素のいずれかのタイプが存在することができのdivクラス内の要素の正確な構造を知っていないことに注意してください。したがって、セレクタは十分に柔軟でなければなりません。ここで

は、私は、このBeautifulSoupコードを追加する必要があり、完全なコード、...

class MySpider(CrawlSpider): 
name = 'dknnews' 
start_urls = ['http://www.example.com/uat-area/scrapy/all-news-listing/_recache'] 
allowed_domains = ['example.com'] 
def parse(self, response): 
     hxs = Selector(response) 
     soup = BeautifulSoup(response.body, 'lxml') 
     #soup = BeautifulSoup(content.decode('utf-8','ignore')) 
     nf = NewsFields() 
     ptype = soup.find_all(attrs={"name":"dknpagetype"}) 
     ptitle = soup.find_all(attrs={"name":"dknpagetitle"}) 
     pturl = soup.find_all(attrs={"name":"dknpageurl"}) 
     ptdate = soup.find_all(attrs={"name":"dknpagedate"}) 
     ptdesc = soup.find_all(attrs={"name":"dknpagedescription"}) 
     for node in soup.find_all("div", class_="apple"): <!-- THIS IS WHERE I NEED TO ADD THE BS CODE --> 
     ptbody = ''.join(node.find_all(text=True)) 
     ptbody = ' '.join(ptbody.split()) 
     nf['pagetype'] = ptype[0]['content'].encode('ascii', 'ignore') 
     nf['pagetitle'] = ptitle[0]['content'].encode('ascii', 'ignore') 
     nf['pageurl'] = pturl[0]['content'].encode('ascii', 'ignore') 
     nf['pagedate'] = ptdate[0]['content'].encode('ascii', 'ignore') 
     nf['pagedescription'] = ptdesc[0]['content'].encode('ascii', 'ignore') 
     nf['bodytext'] = ptbody.encode('ascii', 'ignore') 
     yield nf 
     for url in hxs.xpath('//ul[@class="scrapy"]/li/a/@href').extract(): 
     yield Request(url, callback=self.parse) 

私はBeautifulSoupのfind_allでネストされたセレクタを使用するかどうかはわからないのでしょうか?

ご協力いただきありがとうございます。

おかげ

答えて

0
soup.select('.fruits .apple p') 

使用CSSselectorは、それがクラスを表現するのは非常に簡単です。

soup.find(class_='fruits').find(class_="apple").find_all('p') 

または、ステップ

EDITによってpタグステップを取得するためにfind()を使用することができます。

[s for div in soup.select('.fruits .apple') for s in div.stripped_strings] 

stripped_stringsが得る、divタグの下にあるすべての文字列を取得するためにstringsジェネレータを使用結果に\nを取り除いてください。

アウト:

['John', 'Sam', 'Bailey', 'Jack', 'Sour', 'Sweet', 'Salty', 'Fruits are good'] 

全コード:ご返信用

from bs4 import BeautifulSoup 
source_code = """<div class="container"> 
<div class="fruits"> 
    <div class="apple"> 
     <p>John</p> 
     <p>Sam</p> 
     <p>Bailey</p> 
     <p>Jack</p> 
     <ul> 
      <li>Sour</li> 
      <li>Sweet</li> 
      <li>Salty</li> 
     </ul> 
     <span>Fruits are good</span> 
    </div> 
    <div class="mango"> 
     <p>Randy</p> 
     <p>James</p> 
    </div> 
</div> 
<div class="apple"> 
    <p>Bill</p> 
    <p>Sean</p> 
</div> 
</div> 
""" 
soup = BeautifulSoup(source_code, 'lxml') 
[s for div in soup.select('.fruits .apple') for s in div.stripped_strings] 
+0

感謝。私は質問を更新しました.... – Slyper

+0

ありがとうございますが、クラス 'apple'のコードに2つのdivがあります。あなたのコードは、クラス 'fruits'の下にあるdivだけを対象としていると思いますか? – Slyper

+0

@Puneet Sharmaあなたは質問の出力を変更しました。私はそれを更新します。 –