在Python / BeautifulSoup中,有没有一种方法可以在一系列相似的行中选择特定行?

时间:2019-04-18 14:07:22

标签: python html beautifulsoup

抱歉,标题令人困惑。我是Python的完整入门者,甚至都不知道问这个问题的语言。

我正在尝试对Box Office Mojo网站进行数据清理。我正在寻找一个csv文件,该文件可以为每个国家/地区每年的最高票房收入排行榜(请参阅https://www.boxofficemojo.com/intl/austria/yearly/?yr=2019&p=.htm

我已经能够使用BeautifulSoup来抓取特定页面并对其进行解析:

pip install bs4
from urllib.request import urlopen as uReq
from bs4 import BeautifulSoup as soup

##Creating a variable for the URL I want to use
my_url = 'https://www.boxofficemojo.com/intl/austria/yearly/?yr=2019&p=.htm'

uReq(my_url)
### Opening up connecting, grabbing the page, closing the connection
uClient = uReq(my_url)
page_html = uClient.read() ###Don't run page_html because it may crash the client
uClient.close()
##Using BeuatifulSoup to read the html page and parsing it
page_soup = soup(page_html,"html.parser")

我已经能够隔离要从中获取信息的html的特定行:

container_odd = page_soup.findAll("tr", {"bgcolor":"#ffffff"})
container_even = page_soup.findAll("tr", {"bgcolor":"#f4f4ff"})

我可以看到它抓住了我想要的文本,并且可以不用所有的html格式就可以得到它。

>>>>container_even[0]
<tr bgcolor="#f4f4ff"><td align="center"><font size="2">2</font></td>
<td><font size="2">How to Train Your Dragon: The Hidden World</font></td>
<td><font size="2">UPI</font></td>
<td align="right"><font size="2"><b>$2,701,010</b></font></td>
<td align="center"><font size="2">2/8</font></td>
</tr>
>>> container_odd[0].text
'1\nCaptain Marvel\nDisney\n$3,221,398\n3/7\n'

我还可以在该行中调用第一个“ td项”(我不知道该怎么称呼):

>>> container_odd[0].td.text
'1'

我无法终生解决如何排成一排第二个“ td物品”,即“惊奇队长”。

我现在想要做的是创建一个循环,该循环将从container_even / odd的每一行中提取每个td项以放入列表中。

因此,我希望rank_list包含“ 1、2、3、4 ...”(或者更确切地说是“ 1,3,5 ...”和“ 2,4,6 ...”,因为在这种情况下的代码)

和标题列表,其中包含“ Marvel队长,如何训练龙……”

我不知道如何拉出第二个“ td项目”,然后如何在每一行中循环遍历该项目?

我尝试至少拉出等级项目列表:

    rank  = td[]

    print("rank: " + rank)

但是出现语法错误

  File "scraper.py", line 25
    rank  = td[]
               ^
SyntaxError: invalid syntax

任何帮助创建循环或至少弄清楚如何拉出第二个td物品的帮助,将不胜感激!

2 个答案:

答案 0 :(得分:0)

在注释中查看您的代码:

  
    
      

container_odd [0]。文本       '1 \ n惊奇队长\ n迪士尼\ n $ 3,221,398 \ n3 / 7 \ n'

    
  

您应该能够遍历“ container_odd”对象,并使用for循环以这种方式获取所有行。例如:

for line in container_odd:
    raw_text = line.text
    content_list = raw_text.split('\n')
    print(content_list)

“行”对象将是“ container_odd”对象的每一行,“ raw_text”将看起来像您拉出的内容(我在注释中显示的内容),并通过将其拆分为每一行'\ n'字符,您将拥有一个与您拉出的表匹配的列表。

要将其保存到csv,请尝试以下操作:

def my_csv_writer(text):
    with open(*full\\path\\filename.csv*, 'a+') as file:
        file.write(text)
        file.write('\n')

for line in container_odd:
    raw_text = line.text
    content_list = raw_text.replace(',','').split('\n')
    write_text = ','.join(content_list)
    my_csv_writer(write_text)

该功能将用作您的“写入”功能,当您进行for循环并调用写入功能时,您可以一次将文本写入文件到一行。

答案 1 :(得分:0)

我会更简单地使用熊猫。如果您需要单独的列表,可以将列切成薄片。 list(table['Movie Title'])

全表:

import pandas as pd

table = pd.read_html('https://www.boxofficemojo.com/intl/austria/yearly/?yr=2019&p=.htm')[2]
table.columns = table.iloc[0]
table = table.iloc[1:]
print(table)
table.to_csv(r'C:\Users\User\Desktop\Data.csv', sep=',', encoding='utf-8-sig',index = False )