Złom wielu adresów URL za pomocą QWebPage
Używam QWebPage Qt do renderowania strony używającej javascript do dynamicznej aktualizacji jej zawartości - więc biblioteka, która po prostu pobiera statyczną wersję strony (taka jak urllib2), nie będzie działać.
Mój problem polega na tym, że kiedy renderuję drugą stronę, około 99% czasu program po prostu się zawiesza. Innym razem będzie działać trzy razy przed awarią. Dostałem też kilka segfaultów, ale wszystko jest bardzo przypadkowe.
Domyślam się, że obiekt, którego używam do renderowania, nie jest poprawnie usuwany, więc próba ponownego użycia może powodować pewne problemy dla mnie. Rozejrzałem się i nikt nie wydaje się mieć tego samego problemu.
Oto kod, którego używam. Program pobiera strony internetowe z rynku społecznościowego Steam, dzięki czemu mogę stworzyć bazę danych wszystkich elementów. Muszę zadzwonić dogetItemsFromPage
funkcja wiele razy, aby uzyskać wszystkie przedmioty, ponieważ są podzielone na strony (pokazując wyniki 1-10 z kwoty X).
import csv
import re
import sys
from string import replace
from bs4 import BeautifulSoup
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
class Item:
__slots__ = ("name", "count", "price", "game")
def __repr__(self):
return self.name + "(" + str(self.count) + ")"
def __str__(self):
return self.name + ", " + str(self.count) + ", $" + str(self.price)
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()
self.deleteLater()
def getItemsFromPage(appid, page=1):
r = Render("http://steamcommunity.com/market/search?q=appid:" + str(appid) + "#p" + str(page))
soup = BeautifulSoup(str(r.frame.toHtml().toUtf8()))
itemLst = soup.find_all("div", "market_listing_row market_recent_listing_row")
items = []
for k in itemLst:
i = Item()
i.name = k.find("span", "market_listing_item_name").string
i.count = int(replace(k.find("span", "market_listing_num_listings_qty").string, ",", ""))
i.price = float(re.search(r'\$([0-9]+\.[0-9]+)', str(k)).group(1))
i.game = appid
items.append(i)
return items
if __name__ == "__main__":
print "Updating market items to dota2.csv ..."
i = 1
with open("dota2.csv", "w") as f:
writer = csv.writer(f)
r = None
while True:
print "Page " + str(i)
items = getItemsFromPage(570)
if len(items) == 0:
print "No items found, stopping..."
break
for k in items:
writer.writerow((k.name, k.count, k.price, k.game))
i += 1
print "Done."
PowołaniegetItemsFromPage
raz działa dobrze. Kolejne rozmowy dają mi mój problem. Wyjściem programu jest zazwyczaj
Updating market items to dota2.csv ...
Page 1
Page 2
a potem się zawiesza. Powinien on trwać ponad 700 stron.