2013-05-05 63 views
2

我試圖刮下面網站的實況網球比分。當比賽結束時,我抓取的元素髮生變化,我可以獲得比分,但是在比賽期間,當我搜索保留比分的關聯'span'類時,我將返回該類,但得分爲空(見下文)BeautifulSoup返回不正確的文字

http://www.scoreboard.com/game/6LeqhPJd/#game-summary

score = score.findAll('span',attrs={'class':'scoreboard'}) 

輸出:

[<span class="scoreboard">-</span>, <span class="scoreboard">-</span>] 

預期輸出

[<span class="scoreboard">1</span>, <span class="scoreboard">0</span>] 

使用螢火蟲我可以看到這些字段內的分數,但我似乎無法返回它。誰會知道爲什麼會發生..?

注意:當上述URL中的匹配已完成分數更改的元素時。這只是LIVE匹配的一個問題...

回答

6

該網頁使用的是JavaScript。如果您下載的URL是urllib,那麼JavaScript沒有執行。您在瀏覽器中看到的大部分HTML都沒有生成。

執行JavaScript的一種方法是使用Selenium。 另一種方法是使用PyQt4

import sys 
from PyQt4 import QtWebKit 
from PyQt4 import QtCore 
from PyQt4 import QtGui 

class Render(QtWebKit.QWebPage): 
    def __init__(self, url): 
     self.app = QtGui.QApplication(sys.argv) 
     QtWebKit.QWebPage.__init__(self) 
     self.loadFinished.connect(self._loadFinished) 
     self.mainFrame().load(QtCore.QUrl(url)) 
     self.app.exec_() 

    def _loadFinished(self, result): 
     self.frame = self.mainFrame() 
     self.app.quit() 

url = 'http://www.scoreboard.com/game/6LeqhPJd/#game-summary' 
r = Render(url) 
content = unicode(r.frame.toHtml()) 

一旦你有content後執行JavaScript),你可以用HTML解析器(像BeautifulSoup或LXML)解析它。

例如,使用LXML:

import lxml.html as LH 

def clean(text): 
    return text.replace(u'\xa0', u'') 

doc = LH.fromstring(content) 
result = [] 
for tr in doc.xpath('//tr[td[@class="left summary-horizontal"]]'): 
    row = [] 
    for elt in tr.xpath('td'): 
     row.append(clean(elt.text_content())) 
    result.append(u', '.join(row[1:])) 
print(u'\n'.join(result)) 

產生

Chardy J. (Fra), 2, 6, 77, , , , 
Zeballos H. (Arg), 0, 4, 63, , , , 

使用SeleniumPhantomJS(這樣一個GUI瀏覽器不彈出),這相當於什麼代碼將如下所示:

import selenium.webdriver as webdriver 
import contextlib 
import os 
import lxml.html as LH 

# define path to the phantomjs binary 
phantomjs = os.path.expanduser('~/bin/phantomjs') 
url = 'http://www.scoreboard.com/game/6LeqhPJd/#game-summary' 
with contextlib.closing(webdriver.PhantomJS(phantomjs)) as driver: 
    driver.get(url) 
    content = driver.page_source 
    doc = LH.fromstring(content) 
    result = [] 
    for tr in doc.xpath('//tr[td[@class="left summary-horizontal"]]'): 
     row = [] 
     for elt in tr.xpath('td'): 
      row.append(elt.text_content()) 
     result.append(u', '.join(row[1:])) 
    print(u'\n'.join(result)) 

Selenium/PhantomJS解決方案和PyQt4解決方案的運行時間大致相同。

+0

非常感謝!!只有問題 - :轉換爲JavaScript似乎很慢,如果有更快捷的方式來做到這一點..? – DavidJB 2013-05-05 19:08:13

+0

我對這兩種方法比較熟悉的是Selenium和PyQt4。在這兩者中,我認爲PyQt4在滿足時速度更快。還有其他方法,比如分析JavaScript並查看哪些請求最終提供了您之後的數據。這可能會更快。 – unutbu 2013-05-05 20:48:48