2017-02-04 3 views
0

Я использую BeautifulSoup для проекта. Вот мой HTML структура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> 

Теперь я хочу, чтобы захватить текст в сНу класса «яблоко» который подпадает под класса «плоды»

Это то, что я пытался до сих пор ... .

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

Его возвращение ...

  • Билл
  • Шон

Но я хочу, чтобы вернуться только ...

  • Джон
  • Сэм
  • Бейли
  • Джек
  • Sour
  • Сладкий
  • Соленые
  • Плоды хороши

Пожалуйста, обратите внимание, что я не знаю точную структуру элементов внутри сНу класса = «яблоко» Там может быть любой тип различных HTML-элементов внутри этого класса. Поэтому селектор должен быть достаточно гибким.

Вот полный код, где мне нужно, чтобы добавить этот 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') 

Или, вы можете использовать find(), чтобы получить шаг p тег за шагом

EDIT:

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

использовать strings генератор, чтобы получить всю строку под div тега, stripped_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

Спасибо, но в коде есть 2 divs с классом «apple». Считаете ли вы, что ваш код будет нацелен только на div, который попадает под класс «фрукты»? – Slyper

+0

@Puneet Sharma вы изменили свой результат в вопросе, и я его обновляю. –

Смежные вопросы