1

我正在尝试使用漂亮的汤从网站上抓取数据。默认情况下,此网页显示 18 个项目,单击 javascript 按钮“showAlldevices”后,所有 41 个项目都可见。Beautiful Soup 只为默认情况下可见的项目抓取数据,以获取我使用 PyQt 模块并使用 javascript 代码调用 click 事件的所有项目的数据。以下是参考代码:

import csv
import urllib2
import sys
import time
from bs4 import BeautifulSoup
from PyQt4.QtGui import *  
from PyQt4.QtCore import *  
from PyQt4.QtWebKit import *  

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

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

url = 'http://www.att.com/shop/wireless/devices/smartphones.html'  
r = Render(url)
jsClick = """var evObj = document.createEvent('MouseEvents');
             evObj.initEvent('click', true, true );
             this.dispatchEvent(evObj);
             """

allSelector = "a#deviceShowAllLink" 
allButton   = r.frame.documentElement().findFirst(allSelector)
allButton.evaluateJavaScript(jsClick) 
html = allButton.webFrame().toHtml()


page = html
soup = BeautifulSoup(page)
soup.prettify()
with open('Smartphones_26decv2.0.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',')
    spamwriter.writerow(["Date","Day of Week","Device Name","Price"])
    items = soup.findAll('a', {"class": "clickStreamSingleItem"},text=True)
    prices = soup.findAll('div', {"class": "listGrid-price"})
    for item, price in zip(items, prices):
        textcontent = u' '.join(price.stripped_strings)
        if textcontent:            
            spamwriter.writerow([time.strftime("%Y-%m-%d"),time.strftime("%A") ,unicode(item.string).encode('utf8').strip(),textcontent])

我正在使用这行代码将 html 喂给漂亮的汤html = allButton.webFrame().toHtml()此代码运行时没有任何错误,但我仍然没有获得输出 csv 中所有 41 个项目的数据

我还尝试使用这些代码行将 html 喂给漂亮的汤:

allButton   = r.frame.documentElement().findFirst(allSelector)
a = allButton.evaluateJavaScript(jsClick) 
html = a.webFrame.toHtml()


page = html
soup = BeautifulSoup(page)

但是我遇到了这个错误:html = a.webFrame.toHtml() AttributeError: 'QVariant' object has no attribute 'webFrame'

如果我在这里问任何基本问题,请原谅我的无知,因为我是编程新手并帮助我解决这个问题。

4

1 回答 1

0

我认为您的 JavaScript 代码有问题。由于您正在创建一个MouseEvent对象,因此您应该使用一种initMouseEvent方法进行初始化。你可以在这里找到一个例子。

更新2

但我认为您可以尝试的最简单的想法是使用元素的 JavaScript DOM 方法onclicka而不是使用您自己的 JavaScript 代码。像这样的东西:

allButton.evaluateJavaScript("this.onclick()")

应该管用。我想您必须在单击后重新加载页面,然后再将其传递给解析器。

更新 3

您可以通过r.action(QWebPage.ReloadAndBypassCache)或重新加载页面,r.action(QWebpage.Reload)但它似乎没有任何效果。我试图用 显示页面QWebView,单击链接,看看会发生什么。不幸的是,我遇到了很多分段错误错误,所以我发誓在 PyQt4/Qt4 的某个地方存在错误。由于被废弃的页面使用 jquery,我也尝试在加载 jquery 后显示它,QWebPage但再次没有运气(段错误不会消失)。我放弃了 :( 我希望 SO 的其他用户会帮助你。无论如何,我建议你向PyQt4 邮件列表寻求帮助。他们为 PyQt 用户提供了极好的支持。

更新

更改代码时出现的错误是预期的:记住这allButton是一个QWebElement对象。并且该QWebElement.evaluateJavaScript方法返回一个QVariant对象(如文档中所述)并且那种对象没有webFrame属性,因为您可以检查查看此页面

于 2012-12-27T08:43:48.437 回答