python анализира конкретни данни в html таблица, използвайки lxml и xpath

Първо, аз съм нов в python и Stack Overflow, така че, моля, бъдете любезни.

Това е изходният код на html страницата, от която искам да извлека данни.

Уеб страница: http://gbgfotboll.se/information/?scr=table&ftid=51168 Таблицата е в долната част на страницата

  <html>
        table class="clCommonGrid" cellspacing="0">
                <thead>
                    <tr>
                        <td colspan="3">Kommande matcher</td>
                    </tr>
                    <tr>
                        <th style="width:1%;">Tid</th>
                        <th style="width:69%;">Match</th>
                        <th style="width:30%;">Arena</th>
                    </tr>
                </thead>

                <tbody class="clGrid">

            <tr class="clTrOdd">
                <td nowrap="nowrap" class="no-line-through">
                    <span class="matchTid"><span>2014-09-26<!-- br ok --> 19:30</span></span>



                </td>
                <td><a href="/bg?scr=result&amp;fmid=2669197">Guldhedens IK - IF Warta</a></td>
                <td><a href="/bg?scr=venue&amp;faid=847">Guldheden Södra 1 Konstgräs</a> </td>
            </tr>

            <tr class="clTrEven">
                <td nowrap="nowrap" class="no-line-through">
                    <span class="matchTid"><span>2014-09-26<!-- br ok --> 13:00</span></span>



                </td>
                <td><a href="/bg?scr=result&amp;fmid=2669176">Romelanda UF - IK Virgo</a></td>
                <td><a href="/bg?scr=venue&amp;faid=941">Romevi 1 Gräs</a> </td>
            </tr>

            <tr class="clTrOdd">
            <td nowrap="nowrap" class="no-line-through">
                <span class="matchTid"><span>2014-09-27<!-- br ok --> 13:00</span></span>



            </td>
            <td><a href="/bg?scr=result&amp;fmid=2669167">Kode IF - IK Kongahälla</a></td>
            <td><a href="/bg?scr=venue&amp;faid=912">Kode IP 1 Gräs</a> </td>
        </tr>

        <tr class="clTrEven">
            <td nowrap="nowrap" class="no-line-through">
                <span class="matchTid"><span>2014-09-27<!-- br ok --> 14:00</span></span>



            </td>
            <td><a href="/bg?scr=result&amp;fmid=2669147">Floda BoIF - Partille IF FK </a></td>
            <td><a href="/bg?scr=venue&amp;faid=218">Flodala IP 1</a> </td>
        </tr>


                </tbody>
        </table>
    </html>

Трябва да извлека часа: 19:30 и името на отбора: Guldhedens IK - IF Warta, което означава първата и втората клетка на таблицата (не третата) от първия ред на таблицата и 13:00/Romelanda UF - IK Virgo от втори ред на таблица и т.н.. от всички редове на таблицата има.

Както можете да видите, всеки ред на таблица има дата точно преди часа, така че тук идва сложната част. Искам само да получа времето и имената на отборите, както е споменато по-горе, от онези редове на таблицата, където датата е равна на датата, на която изпълнявам този код.

Единственото нещо, което успях да направя досега, не е много, мога да получа само времето и името на отбора, използвайки този код:

import lxml.html
html = lxml.html.parse("http://gbgfotboll.se/information/?scr=table&ftid=51168")
test=html.xpath("//*[@id='content-primary']/table[3]/tbody/tr[1]/td[1]/span/span//text()")

print test

което ми дава резултата ['2014-09-26', ' 19:30'] след това съм изгубен как да итерирам различни редове на таблица, искайки конкретните клетки на таблицата, където датата съвпада с датата, на която изпълнявам кода.

Надявам се, че можете да отговорите колкото можете.


person Community    schedule 21.09.2014    source източник


Отговори (2)


Ако съм те разбрал, опитай нещо подобно:

import lxml.html
url = "http://gbgfotboll.se/information/?scr=table&ftid=51168"
html = lxml.html.parse(url)
for i in range(12):
    xpath1 = ".//*[@id='content-primary']/table[3]/tbody/tr[%d]/td[1]/span/span//text()" %(i+1)
    xpath2 = ".//*[@id='content-primary']/table[3]/tbody/tr[%d]/td[2]/a/text()" %(i+1)
    print html.xpath(xpath1)[1], html.xpath(xpath2)[0]

Знам, че това е крехко и има по-добри решения, но работи. ;)

Редактиране:
По-добър начин с помощта на BeautifulSoup:

from bs4 import BeautifulSoup
import requests

respond = requests.get("http://gbgfotboll.se/information/?scr=table&ftid=51168")
soup = BeautifulSoup(respond.text)
l = soup.find_all('table')
t = l[2].find_all('tr') #change this to [0] to parse first table
for i in t:
    try:
        print i.find('span').get_text()[-5:], i.find('a').get_text()
    except AttributeError:
        pass

Edit2: страницата не отговаря, но това трябва да работи:

from bs4 import BeautifulSoup
import requests

respond = requests.get("http://gbgfotboll.se/information/?scr=table&ftid=51168")
soup = BeautifulSoup(respond.text)
l = soup.find_all('table')
t = l[2].find_all('tr')
time = ""
for i in t:
    try:
        dateTime = i.find('span').get_text()
        teamName = i.find('a').get_text()
        if time == dateTime[:-5]:
            print dateTime[-5,], teamName
        else:
            print dateTime, teamName
            time = dateTime[:-5]
    except AttributeError:
        pass

lxml:

import lxml.html
url = "http://gbgfotboll.se/information/?scr=table&ftid=51168"
html = lxml.html.parse(url)
dateTemp = ""
for i in range(12):
    xpath1 = ".//*[@id='content-primary']/table[3]/tbody/tr[%d]/td[1]/span/span//      text()" %(i+1)
    xpath2 = ".//*[@id='content-primary']/table[3]/tbody/tr[%d]/td[2]/a/text()" %(i+1)
    time = html.xpath(xpath1)[1]
    date = html.xpath(xpath1)[0]
    teamName = html.xpath(xpath2)[0]
    if date == dateTemp:
        print time, teamName
    else:
        print date, time, teamName
person CodeNinja    schedule 21.09.2014
comment
Защо първият пример е крехък? Ти просто пропусна едно нещо, от което имах нужда. Трябва да отпечатва само времето и имената на отборите, ако датата е същата. Пример: Да речем, че сме изпълнили кода на 2014-09-26, тогава, когато итерираме през таблицата в for цикъла, той трябва да провери дали датата съвпада с датата във всеки ред на таблицата: ‹span class=matchTid›‹span› 2014-09-26 Тогава кодът ще отпечата само: 19:30 Guldhedens IK - IF Warta и 13:00 Romelanda UF - IK Virgo Тъй като датата, която имат, съвпада с датата на изпълнение 2014-09-26 @CodeNinja Ако можете да въведете това в първият пример - person ; 21.09.2014
comment
Бих гласувал, ако можех, но пише, че имам нужда от 15 репутация, за да гласувам. Съжалявам, но се надявам, че все пак ще ми помогнете, ако можете. @CodeNinja - person ; 21.09.2014
comment
Забравихте да отговорите защо е крехък. Също така прочетох, че xpath и lxml са по-доброто решение за използване при анализиране от html страници. Бихте ли могли също да приложите решението за дата към първия си пример с помощта на lxml? Благодаря ти @CodeNinja - person ; 21.09.2014
comment
Редактирано. Не знам добре lxml ;) lxml съдържа методи, чрез които можете да се справите по-добре... Чуплив, защото използвах range(12) това е куцо ;p - person CodeNinja; 21.09.2014
comment
Хаха, добре, да, вярно е, но мисля, че мога да поправя. Все още не мисля, че наистина разбрахте какво исках да направя, но с този код, който ми дадохте, мога да го настроя така, както искам. Ще използвам времето за импортиране, за да получа текущото време. Както и да е, ще публикувам отговор, когато сайтът стане готов и тествах кода, за да се уверя, че ще ви уведомя, когато го направя. Благодаря ти за помощта! :D @CodeNinja - person ; 21.09.2014

И така, благодарение на помощта на @CodeNinja, просто го промених малко, за да получа точно това, което исках. Импортирах време, за да получа датата на времето, когато стартирам кода. Както и да е, тук е кодът за това, което исках. Благодаря ти за помощта!!

import lxml.html
import time
url = "http://gbgfotboll.se/information/?scr=table&ftid=51168"
html = lxml.html.parse(url)
currentDate = (time.strftime("%Y-%m-%d"))
for i in range(12):
    xpath1 = ".//*[@id='content-primary']/table[3]/tbody/tr[%d]/td[1]/span/span//text()" %(i+1)
    xpath2 = ".//*[@id='content-primary']/table[3]/tbody/tr[%d]/td[2]/a/text()" %(i+1)
    time = html.xpath(xpath1)[1]
    date = html.xpath(xpath1)[0]
    teamName = html.xpath(xpath2)[0]
    if date == currentDate:
        print time, teamName

И така, ето ОКОНЧАТЕЛНАТА версия за това как да го направите по правилния начин. Това ще анализира всички редове на таблицата, които има, без да използва "обхват" в for цикъла. Получих този отговор от другата си публикация тук: Итерация през всички редове в таблица с помощта на python lxml xpath

import lxml.html
from lxml.etree import XPath
url = "http://gbgfotboll.se/information/?scr=table&ftid=51168"
date = '2014-09-27'

rows_xpath = XPath("//*[@id='content-primary']/table[3]/tbody/tr[td[1]/span/span//text()='%s']" % (date))
time_xpath = XPath("td[1]/span/span//text()[2]")
team_xpath = XPath("td[2]/a/text()")

html = lxml.html.parse(url)

for row in rows_xpath(html):
    time = time_xpath(row)[0].strip()
    team = team_xpath(row)[0]
    print time, team
person Community    schedule 22.09.2014