【问题标题】:BeautifulSoup returning incorrect textBeautifulSoup 返回不正确的文本
【发布时间】:2013-04-29 11:49:40
【问题描述】:

我正在尝试从以下网站上获取现场网球比分。当匹配结束时,我正在抓取更改的元素并且我可以获得分数,但是在匹配期间,当我搜索保留分数的关联“跨度”类时,我返回该类但分数为空白(见下文)

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 比赛的问题...

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    网页正在使用 JavaScript。如果您正在下载带有urllib 的 URL,则 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 解决方案的运行时间大致相同。

    【讨论】:

    • 谢谢!,效果很好!唯一的问题 - :转换为 javascript 似乎很慢,如果有更快的方法来做到这一点..?
    • 我比较熟悉的两种方法是Selenium和PyQt4。在这两者中,我认为 PyQt4 在足够的情况下会更快。还有其他方法,例如分析 JavaScript 并查看哪些请求最终提供了您所追求的数据。那可能会运行得更快。
    猜你喜欢
    • 2019-03-07
    • 1970-01-01
    • 2020-03-25
    • 2022-11-28
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多