2017-02-04 2 views
0

Ich benutze BeautifulSoup für ein Projekt. Hier ist meine HTML-StrukturBeautifulSoup Nested Klassenselektor

<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> 

Jetzt möchte ich Text in div class 'Apfel' greifen, die unter Klasse fällt 'Früchte'

Dies ist, was ich habe versucht, so weit ...

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

Seine Rückkehr ...

  • Bill
  • Sean

Aber ich will es nur zurück ...

  • John
  • Sam
  • Bailey
  • Jack
  • Sour
  • Süße
  • Salty
  • Früchte sind gut

Bitte beachten Sie, dass ich nicht die genaue Struktur von Elementen innerhalb div class = „apple“ Weiß nicht Es kann innerhalb dieser Klasse jede Art von verschiedenen HTML-Elemente sein. Der Selektor muss also flexibel genug sein. Hier

ist den vollständigen Code, wo ich brauche diesen BeautifulSoup Code hinzufügen ...

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) 

Ich bin nicht sicher, wie verschachtelte Selektoren verwenden, um mit BeautifulSoup find_all?

Jede Hilfe wird sehr geschätzt.

Dank

Antwort

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

Verwendung CSSselector, ist es sehr einfach Klasse auszudrücken.

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

Oder Sie find() verwenden, um die p Tag Schritt für Schritt

EDIT zu erhalten:

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

Verwendung strings Generator bekommen alle die Zeichenfolge unter dem div Tag wird stripped_strings erhalten los von \n in den Ergebnissen.

aus:

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

Voll Code:

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

Vielen Dank für Ihre Antwort. Ich habe die Frage aktualisiert .... – Slyper

+0

Danke, aber es gibt 2 divs im Code mit Klasse "Apfel". Glaubst du, dass dein Code nur auf das div verweist, das unter die Klasse "Früchte" fällt? – Slyper

+0

@Puneet Sharma Sie Ihre Ausgabe in der Frage geändert, und ich aktualisiere es. –