繁体   English   中英

用BeautifulSoup解析html表

[英]Parsing an html table with BeautifulSoup

我正在尝试从此时间表中获取特定日期的数据: 点击此处

我已经可以使用Beautiful Soup使用以下代码将任意给定日期(在这种情况下,星期一或“星期一”)的整行添加到列表中:

from BeautifulSoup import BeautifulSoup

day ='Mon'

with open('timetable.txt', 'rt') as input_file:
  html = input_file.read()
  soup = BeautifulSoup(html)
  #finds correct day tag
  starttag = soup.find(text=day).parent.parent
  print starttag
  nexttag = starttag
  row=[]
  x = 0
  #puts all td tags for that day in a list
  while x < 18:
    nexttag = nexttag.nextSibling.nextSibling
    row.append(nexttag)
    x += 1
print row

如您所见,该命令返回TD标签列表,这些列表组成了时间表中的“ mon”行。

我的问题是,我不知道如何进一步解析或搜索返回的列表以找到相关信息(COMP1740等)。

如果我能找到如何在列表中的每个元素中搜索模块代码,则可以将它们与另一个时间列表并置在一起,给出一天的时间表。

欢迎所有帮助! (包括完全不同的方法)

您可以使用正则表达式查找信息,例如课程编号,即模式匹配。

我不知道您对它们的使用经验,但是Python包含一个“ re”模块。 查看“四个字母COMP后跟一个或多个数字”的模式。 给出COMP\\d+的RegEx,其中\\d是一位数字,以下+表示寻找尽可能多的数字(在这种情况下为4)。

from BeautifulSoup import BeautifulSoup
import re

day ='Mon'
codePat = re.compile(r'COMP\d+')

with open('timetable.txt', 'rt') as input_file:
  html = input_file.read()
  soup = BeautifulSoup(html)
  #finds correct day tag
  starttag = soup.find(text=day).parent.parent
#  print starttag
  nexttag = starttag
  row=[]
  x = 0
  #puts all td tags for that day in a list
  while x < 18:
    nexttag = nexttag.nextSibling.nextSibling
    found = codePat.search(repr(nexttag))
    if found:
      row.append(found.group(0))
    x += 1
print row

这给了我输出

['COMP1940', 'COMP1550', 'COMP1740']

就像我说的,我不知道您对正则表达式的了解在哪里,所以如果您可以描述这些模式,那么我可以尝试编写它们。 如果您决定自己做, 这是一个很好的资源

from BeautifulSoup import BeautifulSoup
import re

#day input
day ='Thu'
#searches for a module (where html has rowspan="1")
module = re.compile(r'rowspan=\"1\"')
#lengths of module search (depending on html colspan attribute)
#1.5 hour
perlen15 = re.compile(r'colspan=\"3\"')
#2 hour
perlen2 = re.compile(r'colspan=\"4\"')
#2.5 hour etc.
perlen25 = re.compile(r'colspan=\"5\"')
perlen3 = re.compile(r'colspan=\"6\"')
perlen35 = re.compile(r'colspan=\"7\"')
perlen4 = re.compile(r'colspan=\"8\"')
#times correspond to first row of timetable.
times = ['8:00', '8:30', '9:00', '9:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00', '15:30']

#opens full timetable html
with open('timetable.txt', 'rt') as input_file:
  html = input_file.read()
  soup = BeautifulSoup(html)
  #finds correct day tag
  starttag = soup.find(text=day).parent.parent
  nexttag = starttag
  row=[]
  #movement of cursor iterating over times list
  curmv = 0
  #puts following td tags for that day in a list
  for time in times:
    nexttag = nexttag.nextSibling.nextSibling
    #detect if a module is found
    found = module.search(repr(nexttag))
    #detect length of that module
    hour15 = perlen15.search(repr(nexttag))
    hour2 = perlen2.search(repr(nexttag))
    hour25 = perlen25.search(repr(nexttag))
    hour3 = perlen3.search(repr(nexttag))
    hour35 = perlen35.search(repr(nexttag))
    hour4 = perlen4.search(repr(nexttag))
    if found: 
      row.append(times[curmv])
      row.append(nexttag)
      if hour15:
        curmv += 3
      elif hour2:
        curmv += 4
      elif hour25:
        curmv += 5
      elif hour3:
        curmv += 6
      elif hour35:
        curmv += 7
      elif hour4:
        curmv += 8
      else:
        curmv += 2
    else:
      curmv += 1
#write day to html file
with open('output.html', 'wt') as output_file:
  for e in row:
    output_file.write(str(e))  

如您所见,代码可以区分一小时和两小时的讲座,以及1.5、2.5小时的讲座等。

我现在唯一的问题是第32行,我需要一种更好的方法来告诉代码停止在整个表中水平移动:知道何时停止for循环(在上一个代码中,我while x < 18:仅适用于星期一因为该行中有18个td标签。当它碰到父标签</tr>时,如何使循环停止?

谢谢!

编辑:我将尝试使用try和except块来捕获如果我将“时间”设置为18:00之前设置的错误。

EDIT2:成功了! :d

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM