LINUX.ORG.RU

Написал граббер анонимных прокси


0

1

Собственно, вот код. Покритикуйте.
Аргумент программы - требуемое число проксей. Выводит их список print'ом, когда наберет это количество.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import fpclib
import time

import thread
import time

import sys

if len(sys.argv) < 2:
  print "%s [N]" % (sys.argv[0])
  sys.exit()
N = int(sys.argv[1])
proxies = []
keywords = u"free proxy"
ports = [(3128,"http"), (1080,"socks4")]
TIMEOUT_GET = 10 # сколько секунд ждать ответа от Google
TIMEOUT_GOOGLE = 2.0 # сколько ждать после обработки всех сайтов(ip), перед следующим запросом к Google
TIMEOUT_CHECK = 15 # сколько ждать прокси-сервер (ответ от него)
TIMEOUT_WHILE = 0.2 # таймаут в цикле ожидания выхода (пока все "висящие" ip не обработаются)
N_T = 50
n_t = 0

def func(proxy_hostname, proxy_port, proxy_type, timeout):
  global n_t
  global proxies
  if fpclib.check_proxy(proxy_hostname, proxy_port, proxy_type, timeout):
    s = "%s:%d" % (ip, proxy_port)
    print "ACCEPT %s" % (s)
    if not s in proxies:
      proxies.append(s)
    print proxies
  n_t = n_t - 1

i = 0
while True:
  url = fpclib.geturl_google_text(keywords,i)
  html = fpclib.gethttp_pycurl(url,TIMEOUT_GET)
  sites = fpclib.cuturi_google(html)
  print sites
  for url_site in sites:
    html = fpclib.gethttp_pycurl(url_site,TIMEOUT_GET)
    ips = fpclib.cutip(html)
    print len(html), ips
    for ip in ips:
      for proxy_port, proxy_type in ports:
        while n_t > N_T:
          time.sleep(TIMEOUT_WHILE)
        n_t = n_t + 1
        thread.start_new(func, (ip, proxy_port, proxy_type, TIMEOUT_CHECK,))
        if len(proxies) >= N: break
      if len(proxies) >= N: break
    if len(proxies) >= N: break
  if len(proxies) >= N: break
  i = i + 1
  time.sleep(TIMEOUT_GOOGLE) # seconds

while n_t > 0:
  time.sleep(TIMEOUT_WHILE)

for proxy in proxies:
  print proxy

fpclib.py:
#!/usr/bin/python
# -*- coding: utf-8 -*-

from StringIO import StringIO
import pycurl

import re

def gethttp_pycurl_f(url,f,timeout=1,proxy_type="none",proxy_hostname="localhost",proxy_port=3128):
  curl = pycurl.Curl()
  curl.setopt(pycurl.URL, url)
  curl.setopt(pycurl.WRITEDATA, f)
  curl.setopt(pycurl.FOLLOWLOCATION, 1)
  curl.setopt(pycurl.MAXREDIRS, 5)
  curl.setopt(pycurl.CONNECTTIMEOUT, timeout)
  curl.setopt(pycurl.TIMEOUT, timeout)
  curl.setopt(pycurl.NOSIGNAL, 1)

  if proxy_type == "http":
    curl.setopt(pycurl.PROXY,proxy_hostname)
    curl.setopt(pycurl.PROXYPORT,proxy_port)
    curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_HTTP)
  elif proxy_type == "socks4":
    curl.setopt(pycurl.PROXY,proxy_hostname)
    curl.setopt(pycurl.PROXYPORT,proxy_port)
    curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_SOCKS4)
  elif proxy_type == "socks5":
    curl.setopt(pycurl.PROXY,proxy_hostname)
    curl.setopt(pycurl.PROXYPORT,proxy_port)
    curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_SOCKS5)

  try:
    curl.perform()
  except Exception,e:
    print "Exception: %s" % str(e)
  curl.close()

def gethttp_pycurl(url,timeout=1,proxy_type="none",proxy_hostname="localhost",proxy_port=3128):
  body = StringIO()
  curl = pycurl.Curl()
  curl.setopt(pycurl.URL, url)
  curl.setopt(pycurl.WRITEFUNCTION, body.write)
  curl.setopt(pycurl.FOLLOWLOCATION, 1)
  curl.setopt(pycurl.MAXREDIRS, 5)
  curl.setopt(pycurl.CONNECTTIMEOUT, timeout)
  curl.setopt(pycurl.TIMEOUT, timeout)
  curl.setopt(pycurl.NOSIGNAL, 1)

  if proxy_type == "http":
    curl.setopt(pycurl.PROXY,proxy_hostname)
    curl.setopt(pycurl.PROXYPORT,proxy_port)
    curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_HTTP)
  elif proxy_type == "socks4":
    curl.setopt(pycurl.PROXY,proxy_hostname)
    curl.setopt(pycurl.PROXYPORT,proxy_port)
    curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_SOCKS4)
  elif proxy_type == "socks5":
    curl.setopt(pycurl.PROXY,proxy_hostname)
    curl.setopt(pycurl.PROXYPORT,proxy_port)
    curl.setopt(pycurl.PROXYTYPE,pycurl.PROXYTYPE_SOCKS5)

  try:
    curl.perform()
  except Exception,e:
    print "Exception: %s" % str(e)
  page = body.getvalue()
  curl.close()
  return page

import urllib

def geturl_rambler_text(text,i):
  site = "http://www.rambler.ru/lite"
  url = urllib.urlencode([
    ("oe","1251"),
    ("words",text.encode("cp1251")),
    ("start",str(int(i)*10+1))])
  return site+"?"+url

def geturl_rambler_images(text,i):
  site = "http://nova.rambler.ru/pictures"
  url = urllib.urlencode([
    ("query",text.encode("utf-8"))])
  return site+"?"+url

def geturl_yandex_text(text,i):
  site = "http://yandex.ru/yandsearch"
  url = urllib.urlencode([
    ("rpt","rad"),
    ("text",text.encode("utf-8")),
    ("p",str(int(i)))])
  return site+"?"+url

def geturl_yandex_images(text,i):
  site = "http://images.yandex.ru/yandsearch"
  url = urllib.urlencode([
    ("stype","image"),
    ("text",text.encode("utf-8"))]) # utf-8
  return site+"?"+url

def geturl_google_text(text,i):
  site = "http://www.google.ru/search"
  url = urllib.urlencode([
    ("hl","ru"),
    ("q",text.encode("utf-8")),
    #("q",text),
    ("start",str(int(i)*10))])
  return site+"?"+url

def geturl_google_images(text,i):
  site = "http://images.google.ru/images"
  url = urllib.urlencode([
    ("hl","ru"),
    ("gbv","2"),
    ("btnG","%D0%9F%D0%BE%D0%B8%D1%81%D0%BA+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA"),
    ("q",text.encode("utf-8"))])
  return site+"?"+url

def cuturi(text):
  a = re.findall("((?:http://|https://|ftp://|gopher://|mailto:|xmpp:)(?:[\w\.]+:\d+)?(?:[^\"\'\t\n\r< >:]+))",text)
  return a

def cuturi_google(text):
  a = re.findall("((?:http://|https://|ftp://|gopher://|mailto:|xmpp:)(?:[\w\.]+:\d+)?(?:[^\"\'\t\n\r< >:]+\" target))",text)
  text = ' '.join(a)
  return cuturi(text)

def cutip(text):
  a = re.findall("(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})",text)
  return a

def check_proxy(proxy_hostname, proxy_port, proxy_type="http", timeout = 30):
  url= "http://ya.ru/"
  html = gethttp_pycurl(url,timeout,proxy_type,proxy_hostname,proxy_port)
  if re.search("http://yandex.ru/", html) <> None:
    res = True
  else:
    res = False
  return res

Страница проекта: http://php.kirovnet.ru/fpcheck.html

★★★★★

А ты его проверил?
Я постоянно пополняю список проксей, не раз сталкивался, что владельцы таких сайтов всячески препятствуют работе таких ботов-парсеров.
У меня роль такого бота выполняют студенты в учебное время: прикрыл VK и иже с ним, и вечером надо просто отфильтровать логи скавида от разрешённых адресов и выбрать из оставшихся адреса проксей и вбить их в банлист.

adriano32 ★★★
()
Ответ на: комментарий от adriano32

> А ты его проверил?

Сейчас попробую вбить хотя бы один найденный в Firefox ...
Странно. Выдает - «Refused connection» все найденные IP:PORT.

Ищу ошибку ...

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

У меня вот такие нашло (PycURL нормально через них данные получает):
62.16.58.215:3128
209.226.31.160:1080
209.226.31.160:3128
219.234.88.23:3128
74.86.14.143:3128
116.228.168.236:1080
118.98.215.10:3128
175.111.89.16:3128
122.194.5.154:1080
202.109.80.106:1080
202.109.80.106:3128

Но firefox - не может ...

pacify ★★★★★
() автор топика
Ответ на: комментарий от rg-400

> У тебя «магия» в программе.

Не понял. Поясни.

и копипаста


Может быть. Пару строчек кода - оттуда, пару строчек кода - отсюда.

pacify ★★★★★
() автор топика
Ответ на: комментарий от pacify

Магические числа.

И количество функций можно уменьшить. А ты их копируешь, меняешь пару строк и вставляешь.

rg-400
()
Ответ на: комментарий от rg-400

> Магические числа.

Почему? \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} - от 1 до 3 цифр (правда, тут «подходят» и 000.000.000.000, 256.0.0.0 и т.п., но они отсеиваются на след. этапе - коннекта через PycURL).

И количество функций можно уменьшить. А ты их копируешь, меняешь пару строк и вставляешь.


Для улучшения читабельности.

pacify ★★★★★
() автор топика
Ответ на: комментарий от adriano32

выбрать из оставшихся адреса проксей и вбить их в банлист


интересен смысел сих огораживаний, студни все= просиживают вконтакте, так еще и время тратят на поиск проксей, преподу тоже есть чем позаниматься вечером. столько гемороя с нулевым выхлопом

Karapuz ★★★★★
()
Ответ на: комментарий от Karapuz

Я не препод, я лаборант, это часть моих обязанностей. Тем более когда «УМВР» в аудитории, почитать логи бывает интересно, я даже несколько сайтов в букмарки добавил после прочитки логов - бывает и такое.
Обычно моих студентов хватает на то, чтоб в гугле вбить «закрыли вконтакте на работе» и пройти по ссылкам с первой страницы, если им повезло и на первой странице результатов оказался свеженький веб-прокси - он отправляется в бан вместе со всеми упомянутыми на той же странице, с которой его скопипастили.
Профит в том, что только самые упорные студенты (а их на пальцах двух рук пересчитать можно) продолжают искать свежие прокси, остальные давно уже привыкли «в этой аудитории, в отличие от других, Вконтакте не работает». Но список тем не менее растёт.

adriano32 ★★★
()
Ответ на: комментарий от pacify

И все же правильный регексп примерно таков: ((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)

GateKeeper ★★
()
Ответ на: комментарий от adriano32

Здорово, профит огромный - хомячки остались без возможности терять время, а из остальных может получиться один-два приличных хакера :)

router ★★★★★
()

зомейчания ниочом:
я где-то читал в интернетах что шебанг лучше #!/usr/bin/env python
еще в пеп8 пишут Use 4 spaces per indentation level и Limit all lines to a maximum of 79 characters.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.