【问题标题】:Python, GTK, Webkit & scraping, big memory problemPython, GTK, Webkit & scraping, 大内存问题
【发布时间】:2011-10-24 14:08:47
【问题描述】:

我正在尝试为网站镜像内容,不幸的是,其中大部分内容是基于 javascript 的,包括生成 href 的代码。这消灭了大多数标准的网络抓取工具(如 httrack),因为它们处理 javascript 的尝试,即使他们确实尝试过,也是非常不可靠的。

所以我决定用 python 编写自己的代码并让 webkit 引擎来处理 HTML。程序逻辑看起来很简单,生成一个 dict,其中 url 被找到作为键,值是 0 或 1,取决于它是否已经被处理。我设法让基本逻辑与 pyqt4 一起工作得相当好,但它总是随机出现段错误,足以让我不信任它,然后我发现了这个:http://blog.motane.lu/2009/06/18/pywebkitgtk-execute-javascript-from-python/

整洁的脚本,它可以工作,但我以前从未在 python 中处理过 gtk。不过,将我的逻辑固定在它周围是相当简单的,但事实证明它有点占用内存。使用 meliae 对其进行分析显示没有占用那么多内存,即使 python 达到 2Gb。该站点有相当多的页面,脚本最终达到 32 位内存限制和段错误。我的假设是代码正在产生越来越多的 webkit 窗口。我不知道如何让它真正关闭或摧毁那些窗户。我试过destroy,里面有一个main_quit,好像没有关闭它。

这应该是相关部分(我希望),但目标网址已更改。我对 url 和 foundurl 使用 dicts 但切换到 anydbm 以防它们出于某种奇怪的原因占用内存。我可能会在某个时候切换回字典:

#!/usr/bin/env python
import sys, thread
import gtk
import webkit
import warnings
from time import sleep
from BeautifulSoup import BeautifulSoup
import re
import os
import anydbm
import copy
from meliae import scanner

warnings.filterwarnings('ignore')

class WebView(webkit.WebView):
    def get_html(self):
        self.execute_script('oldtitle=document.title;document.title=document.documentElement.innerHTML;')
        html = self.get_main_frame().get_title()
        self.execute_script('document.title=oldtitle;')
        self.destroy
        return html

class Crawler(gtk.Window):
    def __init__(self, url, file):
        gtk.gdk.threads_init() # suggested by Nicholas Herriot for Ubuntu Koala
        gtk.Window.__init__(self)
        self._url = url
        self._file = file
        self.connect("destroy",gtk.main_quit)

    def crawl(self):
        view = WebView()
        view.open(self._url)
        view.connect('load-finished', self._finished_loading)
        self.add(view)
        gtk.main()
        return view.get_html()

    def _finished_loading(self, view, frame):
        with open(self._file, 'w') as f:
            f.write(view.get_html())
        gtk.main_quit()

..各种只处理 BeautifulSoup 端的子程序,处理页面,拉出链接,整理它们等等......

def main():
    urls=anydbm.open('./urls','n')
    domain = "stackoverflow.com"
    baseUrl = 'http://'+domain
    urls['/']='0'
    while (check_done(urls) == 0):
        count = 0
        foundurls=anydbm.open('./foundurls','n')
        for url, done in urls.iteritems():
            if done == 1: continue
            print "Processing",url
            urls[str(url)] = '1'
            if (re.search(".*\/$",url)):
                outfile=domain+url+"index.html"
            elif (os.path.isdir(os.path.dirname(os.path.abspath(outfile)))):
                outfile=domain+url+"index.html"
            else:
                outfile=domain+url
            if not os.path.exists(os.path.dirname(os.path.abspath(outfile))):
                os.makedirs(os.path.dirname(os.path.abspath(outfile)))
            crawler = Crawler(baseUrl+url, outfile)
            html=crawler.crawl()
            soup = BeautifulSoup(html.__str__())
            for link in hrefs(soup,baseUrl):
                if not foundurls.has_key(str(link)):
                    foundurls[str(link)] = '0'
            del(html)   #  this is an attempt to get the object to vanish, tried del(Crawler) to no avail
            if count==5:
                scanner.dump_all_objects( 'filename' )
                count = 0
            else:
                count=count+1
        for url, done in foundurls.iteritems():
            if not urls.has_key(str(url)):
                urls[str(url)]='0'
        foundurls.close()
        os.remove('./foundurls')
    urls.close()
    os.remove('./urls')

if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python memory webkit gtk


    【解决方案1】:

    我并没有真正使用过WebKit,但self.destroy不应该改为self.destroy()吗?这可能会导致内存泄漏。

    【讨论】:

    • True.. 但不幸的是,这并不能解决问题,它使 python 段错误。大概它正在从它下面杀死 webkit 或 gtk 并且它不太喜欢它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2018-04-07
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多