PhantomJS 擷圖 亂碼修正

使用PhantomJS拮取網站擷時,有時會因為網站Server的Content-Type沒有指定 charset 造成亂碼。Github 上有一個 issue 也是同樣的問題還沒解決。後來想到可以用 chardet 配上HTTP Proxy 來改寫Content-Type header。以上是一個簡單的script來解決這樣的問題:

from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy
from mimetools import Message
from StringIO import StringIO
import chardet

class DebugInterceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):
    def do_response(self, data):
        request_line, headers_alone = data.split('\r\n', 1)
        headers = Message(StringIO(headers_alone))
        mime = headers['content-type'].split(';')

        if mime[0] == 'text/html':
            encoding = chardet.detect(data)['encoding']
            print '%s\nChanging encoding to : %s' % (request_line, encoding)
            ct = 'text/html; charset=%s' % encoding

            data = data.replace(headers['content-type'], ct)

        return data

if __name__ == '__main__':
    print 'Starting proxy server ...'
    proxy = AsyncMitmProxy()
    proxy.register_interceptor(DebugInterceptor)
    try:
        proxy.serve_forever()
    except KeyboardInterrupt:
        proxy.server_close()

注意這個script依賴 miproxy 在執行這個 script 後,就會啟動一個 HTTP proxy server 在 localhost:8080,接著在執PhanotmJS時加上 --proxy=127.0.0.1:8080 這個參數,即:

$ phantomjs --proxy=127.0.0.1:8080 screenshot.js url test.jpg

這樣 PhantomJS 所有的 request 都會經過這個 proxy server, proxy server 會利用 chardet 偵測編碼,並改寫 Content-Type 裡的 charset。這樣 PhantomsJS 便可以正確識別編碼而擷取正確的截圖。

留言

這個網誌中的熱門文章

成功安裝Vista & Ubuntu Linux 8.04 LTS 雙系統!!!

駕訓班~XD