Разбор HTML-таблицы с BeautifulSoup - PullRequest
2 голосов
/ 03 декабря 2011

Я пытаюсь взять данные данного дня из этого расписания: нажмите здесь

Мне удалось использовать 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 и т. д.).

Если я могу узнать, какищите коды элементов в каждом элементе списка, затем я могу объединить их вместе с другим списком времени, указав расписание на один день.

Любая помощь приветствуется!(включая совершенно разные подходы)

Ответы [ 2 ]

1 голос
/ 04 декабря 2011

Вы можете найти информацию, такую ​​как номера курсов, используя регулярные выражения, т. Е. Сопоставление с образцом.

Я не знаю, как вы с ними работали, но в Python есть модуль 're'.Глядя на схему «Четыре буквы COMP, сопровождаемые одной или несколькими цифрами».дает RegEx COMP\d+, где \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']

Как я уже сказал, я не знаю, где ваши знания о регулярных выражениях, поэтому, если вы сможете описать шаблоны, япопробуй написать им. Вот хороший ресурс , если вы решите сделать это самостоятельно.

0 голосов
/ 04 декабря 2011
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 тэдов.Я заставляю цикл останавливаться, когда он попадает в родительский тег </tr>?

спасибо!

РЕДАКТИРОВАТЬ: я собираюсь попробовать использовать блок try и кроме, чтобы поймать ошибкуесли я установлю 'времена' установить до 18:00.

РЕДАКТИРОВАТЬ2: ЭТО РАБОТАЕТ!: D

...