Python automation script [Release][Bot][Free] BitVisitor Bot v0.9 beta - Earn Bitcoin$!!
'''
This script allows you to use bitvisitor.com without having to open it in a webbrowser. 
However, you will still have to wait the 5 minutes and enter the captchas manually. 
It is mainly a console application, but a small window will ask you for the captchas. 

This script was tested with Python 2.7 on Windows 7. Besides the standard stuff, 
it depends on BeautifulSoup (http://www.crummy.com/software/BeautifulSoup/) 
and PIL (http://www.pythonware.com/products/pil/). 

usage: pyvisitor.py [-h] [-u path] [-a address]

optional arguments:
  -h, --help                      Show this help message and exit.
  -u path, --user-agents path     A path to a file containing a user-agent on each line.
  -a address, --address address   Your bitcoin address. If omitted, you will be prompted.

Created on 02.01.2013
Last update on 29.03.2013
@author: The_Exile
Feel free to drop me a coin or two at 13QgXZGtXYEY9cnEB9mGuD1ZbXMWirTicg
'''

from PIL import Image, ImageTk
from Tkinter import Tk, Entry, Label
from argparse import ArgumentParser
from bs4 import BeautifulSoup
from cStringIO import StringIO
from cookielib import CookieJar
from random import randrange, choice
from time import sleep
from urllib import urlencode
from urllib2 import urlopen, Request, HTTPCookieProcessor, install_opener, build_opener, URLError

class InputWindow:
    def __init__(self, captcha, img=None, p=None):
        root = Tk()
        root.attributes('-topmost', 1)        
        hint = '(Enter - submit, Esc - abort)'
        if img is None:
            root.wm_title('Address')
            hint = 'Please enter your Bitcoin address.\n' + hint        
        else:
            root.wm_title('Captcha {0:.4f}'.format(p))
            img = ImageTk.PhotoImage(img)
            root.img_reference = img
        image = Label(root, image=img, text=hint, compound='top')
        image.pack()
        entry = Entry(root)
        entry.bind('<Escape>', lambda _:root.destroy())
        entry.bind('<Return>', lambda _:(captcha.set(entry.get()), root.destroy()))
        entry.pack()
        entry.focus_set()
        root.update_idletasks()
        xp = (root.winfo_screenwidth() / 2) - (root.winfo_width() / 2) - 8
        yp = (root.winfo_screenheight() / 2) - (root.winfo_height() / 2) - 20
        root.geometry('+%d+%d' % (xp, yp))
        root.mainloop()       

class Captcha:
    def __init__(self): self.value = None
    def set(self, value): self.value = value 

class PyVisitor:
    def __init__(self, address=None, agentFile=None):
        self.__addr = address
        if not address:
            address = Captcha()
            InputWindow(address)
            if not address.value:
                print 'Aborted by user.'
                exit(0)
            self.__addr = address.value
        self.__profit = self.__currentProfit = .0
        self.__currency = ''
        self.__captchaURL = None
        self.__host = 'http://bitvisitor.com/'
        defaultAgent = 'Opera/9.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.01'
        self.__headers = {'Accept':'text/html,application/xhtml+xml,application/xml',
                          'User-Agent':defaultAgent}
        install_opener(build_opener(HTTPCookieProcessor(CookieJar())))
        if agentFile:
            try:
                with open(agentFile) as f:
                    self.__headers['User-Agent'] = choice([agent.rstrip() for agent in f])                
            except:
                print 'Using default User-Agent.'
            print 'User-Agent:', self.__headers['User-Agent']

    def __getCaptchaURL(self, soup):
        captchaImg = soup.find('img', id='siimage')
        if not captchaImg:
            return
        earning = soup.find('h1', 'page-header').contents[1].split()        
        self.__currentProfit = float(earning[0])
        if not self.__currency: self.__currency = earning[1]
        self.__captchaURL = self.__host + captchaImg['src'].lstrip('./')
        return self.__captchaURL
    
    def __wait(self, soup):
        siteFrame = soup.find('iframe', id='mlsFrame')
        if not siteFrame: return
        print 'Visiting', siteFrame['src']
        print 'Getting {0:.4f} {1} in'.format(self.__currentProfit,self.__currency),
        for i in range(5, 0, -1):
            print i,
            sleep(60)
        print 
        sleep(randrange(1, 10))  # just to be sure ;)
  
    def visit(self):        
        req = Request(self.__host, None, self.__headers)
        res = urlopen(req)  # set session cookie
        if 'abuse' in res.geturl():
            print 'ERROR: The IP address was deemed suspicious.'
            return 
        # Please do not change the address in the next line. It costs you nothing, but it helps me. 
        params = urlencode({'addr':self.__addr, 'ref':'1Mj8JCYJDjDKMjmvsTrpVPap4BvFyGZVCm'})
        url = self.__host + 'next.php'
        self.__headers['Referer'] = url
        req = Request(url, params, self.__headers)
        while True:
            res = urlopen(req)
            if 'abuse' in res.geturl():
                print 'ERROR: The IP address was deemed suspicious.'
                break
            soup = BeautifulSoup(res.read())
            if not self.__getCaptchaURL(soup): break
            a = None
            while not a:
                captcha = Captcha()
                InputWindow(captcha, Image.open(StringIO(urlopen(self.__captchaURL).read())), self.__currentProfit)
                if not captcha.value:
                    print 'Aborted by user.'
                    break
                cParams = urlencode({'ct_captcha':captcha.value, 'addr':self.__addr})
                soup = BeautifulSoup(urlopen(Request(url, cParams, self.__headers)).read())
                form = soup.find('form', action='next.php')
                if not form:
                    message = soup.get_text()
                    if 'Incorrect' in message: continue
                    print message
                    break
                a = form.find('input', {'name':'a'})['value']
                if a: break
            if not a:  # aborted by user or site error
                break
            self.__wait(soup)            
            nParams = urlencode({'addr':self.__addr, 'a':a})
            res = urlopen(Request(url, nParams, self.__headers))
            if not res:
                break
            self.__profit += self.__currentProfit
            print 'Earned {0:.4f} {1} ({2:.4f} {1})'.format(self.__currentProfit, self.__currency, self.__profit)
        print 'Exiting with {0} {1} earned.'.format(self.__profit, self.__currency)

def main():
    parser = ArgumentParser()
    parser.add_argument('-u', '--user-agents', metavar='path',
                        help='A path to a file containing a user-agent on each line.')
    parser.add_argument('-a', '--address', metavar='address',
                        help='Your bitcoin address. If omitted, you will be prompted.')
    ns = parser.parse_args()
    try:
        PyVisitor(ns.address, ns.user_agents).visit()
    except URLError as e:
        print str(e)

if __name__ == "__main__":
    main()