我正在创建一个基于Django的scraper,用户可以在其中输入搜索词。我使用该搜索词来构建URL并查询该站点,然后返回未呈现的HTML和JS。然后,我可以接受发布请求,通过创建Qwebpage呈现页面,将URL传递给URL并抓取框架的呈现HTML。这在我的Django应用程序中运行一次,下一个POST请求崩溃了该站点。
我首先担心的是,在当前的设置中,我被迫使用xvfb-run包装器来运行。这会在我部署时出现问题 - 更好的问题是:我能以某种方式在生产中使用xvfb包装吗?
据说我可以发一个帖子请求,这会返回我正在寻找的页面。如果我回击并发送另一个请求,我在控制台中看到以下错误,然后关闭./manage.py服务器:
WARNING: QApplication was not created in the main() thread.
QObject::connect: Cannot connect (null)::configurationAdded(QNetworkConfiguration) to QNetworkConfigurationManager::configurationAdded(QNetworkConfiguration)
QObject::connect: Cannot connect (null)::configurationRemoved(QNetworkConfiguration) to QNetworkConfigurationManager::configurationRemoved(QNetworkConfiguration)
QObject::connect: Cannot connect (null)::configurationChanged(QNetworkConfiguration) to QNetworkConfigurationManager::configurationChanged(QNetworkConfiguration)
QObject::connect: Cannot connect (null)::onlineStateChanged(bool) to QNetworkConfigurationManager::onlineStateChanged(bool)
QObject::connect: Cannot connect (null)::configurationUpdateComplete() to QNetworkConfigurationManager::updateCompleted()
Segmentation fault (core dumped)
我承认我不明白错误是什么,因为我对线程概念很新。我不确定这个错误是否意味着它不能重新连接到已经运行的xvfb包装器,或者它确实是一个线程问题。有效的代码就在这里。由于我不想显示我实际抓取的网站,因此略有改变。此外,我不是在寻找此示例中的数据。此示例将简单地将呈现的HTML作为测试提供给您的浏览器:
import sys
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.views.generic import View
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtWebKit import *
from bs4 import BeautifulSoup
from .forms import QueryForm
def query(request):
results = google.search("Real Estate")
context = {'results': results}
return render(request, 'searchlistings/search.html', context)
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()
class SearchView(View):
form_class = QueryForm
template_name = 'searchlistings/index.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
query = form.cleaned_data['query']
context = self.isOnSite(query)
#return context
#return render(request, 'searchlistings/search.html', {'context': context})
return HttpResponse(context)
def isOnSite(self, query):
url = "http://google.com"
#This does the magic.Loads everything
r = Render(url)
#result is a QString.
result = r.frame.toHtml()
r.app.quit()
return result;
所以我的主要问题是:
这里的XVFB包装器是否合适,我是否可以在不同的主机上使用此设置。这不会在我当地的流浪盒上工作吗?
main()线程问题 - 这是一个线程问题还是没有连接回xvfb服务器的问题?这个问题可以通过Celery或类似方法解决吗?
这是做我想要的合适方式吗?我已经看到很多其他解决方案,包括scrapyjs,spynner,selenium等,但它们看起来要么过于复杂,要么基于QT。一个更好的问题是这些替代包中的任何一个解决了main()线程问题吗?
感谢您的帮助!
答案 0 :(得分:0)
确定这里的解决方案是使用twill,如此处所记录的http://twill.idyll.org/python-api.html - 我能够在没有xvfb包装器的情况下运行它,并且它比以前的方法快得多,而且开销更少。我可以推荐这个。