【问题标题】:Web Scraping | Beautiful Soup | Parsing Tables网页抓取 |美丽的汤|解析表
【发布时间】:2017-08-10 05:05:50
【问题描述】:

在这方面有一些很棒的主题(其中一些帮助我达到了这一点),但我似乎无法弄清楚为什么我的程序不工作。

问题:该程序可以运行,但它似乎只在应该循环遍历所有表行时才返回第一行。

我正在使用 Python 3.5

import requests
from bs4 import BeautifulSoup
import pandas as pd

url = "http://www.the-numbers.com/movies/year/2006"

r = requests.get(url)
soup = BeautifulSoup(r.content)

data = []

for table_row in soup.select("table"):
    cells = table_row.find_all(['td'])
    release_date = cells[0].text.strip()
    movie_name = cells[2].text.strip()
    genre_name = cells[3].text.strip()
    production_budget = cells[4].text.strip()
    box_office = cells[5].text.strip()
    movie = {"Release_Date" : release_date, 
             "Movie_Name" : movie_name, 
             "Genre" : genre_name, 
             "Production_Budget" : production_budget, 
             "Box_Office" : box_office}
    data.append(movie)
    print (release_date, movie_name, genre_name, production_budget, box_office)

这将返回 2006 年 1 月 BloodRayne Action $25,000,000 $2,405,420,这是正确的,但我需要表中的所有其他行。

如果这个问题很容易解决,下一步就是将其放入 Pandas DataFrame 中(但在响应中不是必需的)。

任何帮助将不胜感激。

【问题讨论】:

    标签: python pandas web-scraping beautifulsoup


    【解决方案1】:

    您可以使用read_html 进行一些数据清理:

    df = pd.read_html('http://www.the-numbers.com/movies/year/2006', header=0)[0]
    df = df.dropna(how='all')
    df['Release Date'] = df['Release Date'].ffill()
    print (df.head())
        Release Date          Movie   Genre ProductionBudget  \
    0  January, 2006            NaN     NaN              NaN   
    1      January 6     BloodRayne  Action      $25,000,000   
    2      January 6       Fateless   Drama      $12,000,000   
    3      January 6  Grandma's Boy  Comedy       $5,000,000   
    4      January 6         Hostel  Horror       $4,800,000   
    
      DomesticBox Officeto Date  Trailer  
    0                       NaN      NaN  
    1                $2,405,420      NaN  
    2                  $196,857      NaN  
    3                $6,090,172      NaN  
    4               $47,326,473      NaN  
    

    您原来的解决方案:

    data = []
    #find first table
    tab = soup.select("table")[0]
    #find all tr elements
    rows = tab.find_all(['tr'])
    #loop anf find all td
    for row in rows:
        cols = row.find_all('td')
        #parse text
        cols = [ele.text.strip() for ele in cols]
        #[:-1] remove last column
        data.append(cols[:-1])
    
    cols = ['Release_Date','Movie_Name','Genre','Production_Budget','DomesticBox']
    #[2:] remove first 2 rows
    df = pd.DataFrame(data[2:], columns = cols)
    print (df.head())
      Release_Date     Movie_Name   Genre Production_Budget  DomesticBox
    0    January 6     BloodRayne  Action       $25,000,000   $2,405,420
    1                    Fateless   Drama       $12,000,000     $196,857
    2               Grandma's Boy  Comedy        $5,000,000   $6,090,172
    3                      Hostel  Horror        $4,800,000  $47,326,473
    4               Kill the Poor                                     $0
    

    【讨论】:

    • 这是完美的,正是我想要的。非常感谢你。出于好奇,你知道为什么我的原始代码只返回第一行吗?
    • 我认为你需要在 td 元素中循环,而不是在表格中,因为表格只是一个。
    • 太完美了——谢谢你帮助我。非常感谢,它工作得很好。问题解决了:)
    • 快速提问 - 为什么将 [0] 放在 tab 变量的末尾?
    • 因为soup.select("table") 返回网页中所有可能表格的列表。所以在这个网页中它返回一个元素列表并选择列表的第一个值是[0]
    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 2019-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2022-10-20
    • 2021-12-06
    相关资源
    最近更新 更多