我正在使用PyQt和美丽汤的组合来从网页上抓取数据。 PyQt被用作Python和Javascript之间的解释器。我正在调用“onclick”事件并试图在“点击”事件之后将该html提供给Beautiful soup。以下是推荐代码:
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.frame.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])
现在运行之后,我得到了下面提到的错误:
File "D:\Microsoft\Pricing\2012-12-26\AT&T_attempt2code.py", line 32, in <module>
html = allButton.frame.toHtml()
AttributeError: 'QWebElement' object has no attribute 'frame'
请帮助我解决这个问题并赦免我的无知,因为我是编程新手。
答案 0 :(得分:0)
如错误消息中所述,问题在于:
html = allButton.frame.toHtml()
allButton
没有frame
属性,因为它是QWebElement
的实例(其定义的转换序列为Render
- &gt; {{1 } - &gt; QWebFrame
- &gt; QWebElement
)。
在您的代码中,QWebElement
方法中定义了frame
属性,因此只有Render._loadFinished
对象具有r
属性。
如果将frame
定义更改为:
html
或者:
html = r.frame.toHtml()