通过div和多个元素的Python BeautifulSoup循环

时间:2020-10-06 16:00:26

标签: python beautifulsoup

我有一个包含电影列表的网站,我整理了该网站的简化HTML。请注意,在现实世界中,<ul>标签不是film_listing或showtime类的直接子级。它们位于几个<div><ul>元素下。

<li class="film_listing">
       <h3 class="film_title">James Bond</h3>
       <ul class="showtimes">
              <li class="showtime">
                     <p class="start_time">15:00</p>
              </li>
              <li class="showtime">
                     <p class="start_time">19:00</p>
                     <ul class="attributes">
                            <li class="audio_desc">
                            </li>
                            <li class="open_cap">
                            </li>
                     </ul>
              </li>
       </ul>
</li>

我创建了一个Python脚本来抓取该网站,该网站目前列出了所有影片的标题以及每个影片的第一个放映时间和第一个属性。但是,我试图列出所有放映时间。最终目的是仅列出带有开放字幕的电影标题以及这些开放字幕的表演的放映时间。

这是带有嵌套的for循环的python脚本,该脚本不起作用,无法打印所有电影的所有放映时间,而不是特定电影的放映时间。还没有设置它仅列出字幕电影。我怀疑逻辑可能是错误的,将不胜感激。谢谢!

for i in soup.findAll('li', {'class':'film_listing'}):
    film_title=i.find('h3', {'class':'film_title'}).text  
    print(film_title)
 
    for j in soup.findAll('li', {'class':'showtime'}):
            print(j['showtime.text'])   

    #For the time listings, find ones with Open Captioned
    i=filmlisting.find('li', {'class':'open_cap'})
    print(film_access)

编辑:对HTML脚本的小修正

2 个答案:

答案 0 :(得分:1)

有许多方法可以提取信息。一种方法是“向后搜索” 。用<li>搜索class="open_cap",并找到先前的开始时间和电影标题:

from bs4 import BeautifulSoup


txt = '''
<li class="film_listing">
       <h3 class="film_title">James Bond</h3>
       <ul class="showtimes">
              <li class="showtime">
                     <p class="start_time">15:00</p>
              </li>
              <li class="showtime">
                     <p class="start_time">19:00</p>
                     <ul class="attributes">
                            <li class="audio_desc">
                            </li>
                            <li class="open_cap">
                            </li>
                     </ul>
              </li>
       </ul>
</li>'''

soup = BeautifulSoup(txt, 'html.parser')


for open_cap in soup.select('.open_cap'):
    print('Name       :', open_cap.find_previous(class_='film_title').text)
    print('Start time :', open_cap.find_previous(class_='start_time').text)
    print('-' * 80)

打印:

Name       : James Bond
Start time : 19:00
--------------------------------------------------------------------------------

答案 1 :(得分:0)

read.html

的内容
<li class="film_listing">
  <h3 class="film_title">James Bond</h3>
  <ul class="showtimes">
    <li class="showtime">
      <p class="start_time">15: 00</p>
    </li>
    <li class="showtime">
      <p class="start_time">19:00</p>
      <ul class="attributes">
        <li class="audio_desc"></li>
        <li class="open_cap"></li>
      </ul>
    </li>
  </ul>
</li>

您曾说过<ul>标签不是类film_listingshowtime的直接子代,那么您可以尝试find()获取具有指定标签名称的第一个元素,或者使用find_all()获取具有指定标签名称的元素列表。 你可以试试这个

    from bs4 import BeautifulSoup as bs
    
    text = open("read.html", "r")
    
    soup = bs(text.read(), 'html.parser')
    
    for listing in soup.find_all("li", class_="film_listing"):
        print("Film name: ", listing.find("h3", class_="film_title").text)
        print("Start time: ", listing.find("p", class_="start_time").text)
   

输出:

Film name:  James Bond
Start time:  15: 00

您可以使用find()方法来代替find_all(),该方法将返回所有名称为<p>和类start_time的标签