¿Cómo hacer peticiones urllib2 a través de Tor en Python?

Estoy tratando de rastrear sitios web usando un rastreador escrito en Python. Quiero integrar Tor con Python, lo que significa que quiero rastrear el sitio de forma anónima utilizando Tor.

Intenté hacer esto. No parece funcionar. Comprobé que mi IP sigue siendo la misma que antes de usar tor. Lo comprobé a través de python.

import urllib2 proxy_handler = urllib2.ProxyHandler({"tcp":"http://127.0.0.1:9050"}) opener = urllib2.build_opener(proxy_handler) urllib2.install_opener(opener) 

Está intentando conectarse a un puerto SOCKS: Tor rechaza cualquier tráfico que no sea SOCKS. Puede conectarse a través de un intermediario, Privoxy, utilizando el puerto 8118.

Ejemplo:

 proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"}) opener = urllib2.build_opener(proxy_support) opener.addheaders = [('User-agent', 'Mozilla/5.0')] print opener.open('http://www.google.com').read() 

También tenga en cuenta las propiedades pasadas a ProxyHandler, sin http prefijando el ip: port

 pip install PySocks 

Entonces:

 import socket import socks import urllib2 ipcheck_url = 'http://checkip.amazonaws.com/' # Actual IP. print(urllib2.urlopen(ipcheck_url).read()) # Tor IP. socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9050) socket.socket = socks.socksocket print(urllib2.urlopen(ipcheck_url).read()) 

El uso de solo urllib2.ProxyHandler como en https://stackoverflow.com/a/2015649/895245 falla con:

 Tor is not an HTTP Proxy 

Mencionado en: ¿Cómo puedo usar un proxy SOCKS 4/5 con urllib2?

Probado en Ubuntu 15.10, Tor 0.2.6.10, Python 2.7.10.

Usar privoxy como http-proxy delante de tor funciona para mí, aquí hay una plantilla de rastreador:

 import urllib2 import httplib from BeautifulSoup import BeautifulSoup from time import sleep class Scraper(object): def __init__(self, options, args): if options.proxy is None: options.proxy = "http://localhost:8118/" self._open = self._get_opener(options.proxy) def _get_opener(self, proxy): proxy_handler = urllib2.ProxyHandler({'http': proxy}) opener = urllib2.build_opener(proxy_handler) return opener.open def get_soup(self, url): soup = None while soup is None: try: request = urllib2.Request(url) request.add_header('User-Agent', 'foo bar useragent') soup = BeautifulSoup(self._open(request)) except (httplib.IncompleteRead, httplib.BadStatusLine, urllib2.HTTPError, ValueError, urllib2.URLError), err: sleep(1) return soup class PageType(Scraper): _URL_TEMPL = "http://foobar.com/baz/%s" def items_from_page(self, url): nextpage = None soup = self.get_soup(url) items = [] for item in soup.findAll("foo"): items.append(item["bar"]) nexpage = item["href"] return nextpage, items def get_items(self): nextpage, items = self._categories_from_page(self._START_URL % "start.html") while nextpage is not None: nextpage, newitems = self.items_from_page(self._URL_TEMPL % nextpage) items.extend(newitems) return items() pt = PageType() print pt.get_items() 

Aquí hay un código para descargar archivos usando tor proxy en python: (actualizar url)

 import urllib2 url = "http://sofes.miximages.com/python/Donald_Duck2.gif" proxy = urllib2.ProxyHandler({'http': '127.0.0.1:8118'}) opener = urllib2.build_opener(proxy) urllib2.install_opener(opener) file_name = url.split('/')[-1] u = urllib2.urlopen(url) f = open(file_name, 'wb') meta = u.info() file_size = int(meta.getheaders("Content-Length")[0]) print "Downloading: %s Bytes: %s" % (file_name, file_size) file_size_dl = 0 block_sz = 8192 while True: buffer = u.read(block_sz) if not buffer: break file_size_dl += len(buffer) f.write(buffer) status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size) status = status + chr(8)*(len(status)+1) print status, f.close() 

El siguiente código es 100% de trabajo en Python 3.4

(necesitas mantener abierto el Navegador TOR usando este código)

Esta secuencia de comandos se conecta a TOR a través de socks5 para obtener la IP de checkip.dyn.com, cambiar la identidad y reenviar la solicitud para obtener la nueva IP (realiza un bucle 10 veces)

Es necesario instalar las bibliotecas adecuadas para que esto funcione. (Disfruta y no abuses)

 import socks import socket import time from stem.control import Controller from stem import Signal import requests from bs4 import BeautifulSoup err = 0 counter = 0 url = "checkip.dyn.com" with Controller.from_port(port = 9151) as controller: try: controller.authenticate() socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9150) socket.socket = socks.socksocket while counter < 10: r = requests.get("http://checkip.dyn.com") soup = BeautifulSoup(r.content) print(soup.find("body").text) counter = counter + 1 #wait till next identity will be available controller.signal(Signal.NEWNYM) time.sleep(controller.get_newnym_wait()) except requests.HTTPError: print("Could not reach URL") err = err + 1 print("Used " + str(counter) + " IPs and got " + str(err) + " errors") 

La siguiente solución funciona para mí en Python 3 . Adaptado de la respuesta de CiroSantilli:

Con urllib (nombre de urllib2 en Python 3):

 import socks import socket from urllib.request import urlopen url = 'http://icanhazip.com/' socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9150) socket.socket = socks.socksocket response = urlopen(url) print(response.read()) 

Con requests :

 import socks import socket import requests url = 'http://icanhazip.com/' socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9150) socket.socket = socks.socksocket response = requests.get(url) print(response.text) 

Con Selenium + PhantomJS:

 from selenium import webdriver url = 'http://icanhazip.com/' service_args = [ '--proxy=localhost:9150', '--proxy-type=socks5', ] phantomjs_path = '/your/path/to/phantomjs' driver = webdriver.PhantomJS( executable_path=phantomjs_path, service_args=service_args) driver.get(url) print(driver.page_source) driver.close() 

Nota : si planea usar Tor a menudo, ¡considere hacer una donación para apoyar su increíble trabajo!

Actualización : la última (más de v2.10.0) biblioteca de requests admite proxy de calcetines con un requisito adicional de requests[socks] .

Instalación

 pip install requests requests[socks] 

Uso básico

 import requests session = requests.session() # Tor uses the 9050 port as the default socks port session.proxies = {'http': 'socks5://127.0.0.1:9050', 'https': 'socks5://127.0.0.1:9050'} # Make a request through the Tor connection # IP visible through Tor print session.get("http://httpbin.org/ip").text # Above should print an IP different than your public IP # Following prints your normal public IP print requests.get("http://httpbin.org/ip").text 

Respuesta antigua : aunque se trata de una publicación antigua, responda porque nadie parece haber mencionado la biblioteca requesocks .

Es básicamente un puerto de la biblioteca de requests . Tenga en cuenta que la biblioteca es una bifurcación antigua (última actualización 2013-03-25) y es posible que no tenga las mismas funcionalidades que la biblioteca de solicitudes más reciente.

Instalación

 pip install requesocks 

Uso básico

 # Assuming that Tor is up & running import requesocks session = requesocks.session() # Tor uses the 9050 port as the default socks port session.proxies = {'http': 'socks5://127.0.0.1:9050', 'https': 'socks5://127.0.0.1:9050'} # Make a request through the Tor connection # IP visible through Tor print session.get("http://httpbin.org/ip").text # Above should print an IP different than your public IP # Following prints your normal public IP import requests print requests.get("http://httpbin.org/ip").text 

Tal vez usted está teniendo algunos problemas de conectividad de red? El script anterior funcionó para mí (sustituí una URL diferente, usé http://stackoverflow.com/ ) y obtengo la página como se esperaba:

    Stack Overflow  

(etc.)

Tor es un proxy de calcetines. Conectarse a él directamente con el ejemplo que usted cita falla con “error de urlopen Falló la conexión del túnel: 501 Tor no es un proxy HTTP”. Como otros han mencionado, puedes solucionar esto con Privoxy.

Alternativamente, también puede utilizar PycURL o SocksiPy. Para ejemplos de uso de ambos con tor ver …

https://stem.torproject.org/tutorials/to_russia_with_love.html

puedes usar torify

ejecuta tu progtwig con

 ~$torify python your_program.py 

Pensé que solo compartiría una solución que funcionara para mí (python3, windows10):

Paso 1: Habilita tu Tor ControlPort en 9151 .

El servicio Tor se ejecuta en el puerto predeterminado 9150 y ControlPort en 9151 . Debería poder ver la dirección local 127.0.0.1:9150 y 127.0.0.1:9151 cuando ejecuta netstat -an .

 [go to windows terminal] cd ...\Tor Browser\Browser\TorBrowser\Tor tor --service remove tor --service install -options ControlPort 9151 netstat -an 

Paso 2: script de Python como sigue.

 # library to launch and kill Tor process import os import subprocess # library for Tor connection import socket import socks import http.client import time import requests from stem import Signal from stem.control import Controller # library for scraping import csv import urllib from bs4 import BeautifulSoup import time def launchTor(): # start Tor (wait 30 sec for Tor to load) sproc = subprocess.Popen(r'.../Tor Browser/Browser/firefox.exe') time.sleep(30) return sproc def killTor(sproc): sproc.kill() def connectTor(): socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9150, True) socket.socket = socks.socksocket print("Connected to Tor") def set_new_ip(): # disable socks server and enabling again socks.setdefaultproxy() """Change IP using TOR""" with Controller.from_port(port=9151) as controller: controller.authenticate() socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9150, True) socket.socket = socks.socksocket controller.signal(Signal.NEWNYM) def checkIP(): conn = http.client.HTTPConnection("icanhazip.com") conn.request("GET", "/") time.sleep(3) response = conn.getresponse() print('current ip address :', response.read()) # Launch Tor and connect to Tor network sproc = launchTor() connectTor() # list of url to scrape url_list = [list of all the urls you want to scrape] for url in url_list: # set new ip and check ip before scraping for each new url set_new_ip() # allow some time for IP address to refresh time.sleep(5) checkIP() ''' [insert your scraping code here: bs4, urllib, your usual thingy] ''' # remember to kill process killTor(sproc) 

Esta secuencia de comandos anterior renovará la dirección IP para cada URL que desee eliminar. Solo asegúrate de dormir el tiempo suficiente para que cambie la IP. Última prueba ayer. ¡Espero que esto ayude!

Para ampliar el comentario anterior sobre el uso de torify y el navegador Tor (y no necesita Privoxy):

 pip install PySocks pip install pyTorify 

(instala el navegador Tor y ponlo en marcha)

Uso de línea de comando:

 python -mtorify -p 127.0.0.1:9150 your_script.py 

O integrado en un script:

 import torify torify.set_tor_proxy("127.0.0.1", 9150) torify.disable_tor_check() torify.use_tor_proxy() # use urllib as normal import urllib.request req = urllib.request.Request("http://....") req.add_header("Referer", "http://...") # etc res = urllib.request.urlopen(req) html = res.read().decode("utf-8") 

Tenga en cuenta que el navegador Tor utiliza el puerto 9150, no 9050