J'essaie d'explorer des sites Web à l'aide d'un robot écrit en Python. Je souhaite intégrer Tor à Python, ce qui signifie que je souhaite explorer le site de manière anonyme à l’aide de Tor.
J'ai essayé de faire ça. Cela ne semble pas fonctionner. J'ai vérifié mon adresse IP, elle est toujours la même que celle avant d'utiliser tor. Je l'ai vérifié via python.
import urllib2
proxy_handler = urllib2.ProxyHandler({"tcp":"http://127.0.0.1:9050"})
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)
Vous essayez de vous connecter à un port SOCKS - Tor refuse tout trafic non-SOCKS. Vous pouvez vous connecter via un intermédiaire - Privoxy - via le port 8118.
Exemple:
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()
Veuillez également noter les propriétés transmises à ProxyHandler, pas de préfixe http pour ip: port
pip install PySocks
Ensuite:
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())
L'utilisation de urllib2.ProxyHandler
comme dans https://stackoverflow.com/a/2015649/895245 échoue avec
Tor is not an HTTP Proxy
Mentionné à: Comment utiliser un proxy SOCKS 4/5 avec urllib2?
Testé sur Ubuntu 15.10, Tor 0.2.6.10, Python 2.7.10.
La solution suivante fonctionne pour moi dans Python 3. Adapté de CiroSantilli's réponse :
Avec urllib
(nom 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())
Avec 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)
Avec 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()
Note: Si vous prévoyez d’utiliser Tor fréquemment, envisagez de faire un don pour soutenir leur formidable travail!
Voici un code pour télécharger des fichiers en utilisant tor proxy en python: (update url)
import urllib2
url = "http://www.disneypicture.net/data/media/17/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()
Mise à jour - La dernière (à partir de la v2.10.0) requests
library prend en charge les proxy de chaussettes avec une exigence supplémentaire de requests[socks]
.
Installation -
pip install requests requests[socks]
Utilisation de base -
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
Ancienne réponse - Même s’il s’agit d’un ancien message, il ne répond pas car personne ne semble avoir mentionné la requesocks
library.
Il s’agit essentiellement d’un port de la bibliothèque requests
. Veuillez noter que la bibliothèque est un ancien fork (dernière mise à jour le 2013-03-25) et peut ne pas avoir les mêmes fonctionnalités que la dernière bibliothèque de requêtes.
Installation -
pip install requesocks
Utilisation de base -
# 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
Utiliser privoxy comme proxy http devant tor fonctionne pour moi - voici un modèle de robot d'exploration:
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()
Le code suivant fonctionne à 100% sur Python 3.4
(vous devez garder TOR Browser ouvert pour pouvoir utiliser ce code)
Ce script se connecte à TOR via socks5 pour obtenir l’adresse IP de checkip.dyn.com, pour changer d’identité et pour renvoyer la demande afin d’obtenir la nouvelle adresse IP (boucle 10 fois).
Vous devez installer les bibliothèques appropriées pour que cela fonctionne. (Profiter et ne pas abuser)
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")
Peut-être avez-vous des problèmes de connectivité réseau? Le script ci-dessus a fonctionné pour moi (j'ai substitué une URL différente - j'ai utilisé http://stackoverflow.com/
- et j'ai la page comme prévu:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd" >
<html> <head>
<title>Stack Overflow</title>
<link rel="stylesheet" href="/content/all.css?v=3856">
(etc.)
Je pensais partager une solution qui fonctionnait pour moi (python3, windows10):
Étape 1: Activez votre Tor ControlPort à 9151
.
Le service Tor fonctionne sur le port par défaut 9150
et ControlPort sur 9151
. Vous devriez pouvoir voir l'adresse locale 127.0.0.1:9150
et 127.0.0.1:9151
lorsque vous exécutez netstat -an
.
[go to windows terminal]
cd ...\Tor Browser\Browser\TorBrowser\Tor
tor --service remove
tor --service install -options ControlPort 9151
netstat -an
Étape 2: Script Python comme suit.
# 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)
Ce script ci-dessus renouvellera l'adresse IP pour chaque URL que vous souhaitez gratter. Assurez-vous juste de dormir suffisamment longtemps pour que l'IP change. Dernière testée hier. J'espère que cela t'aides!
Pour développer le commentaire ci-dessus sur l'utilisation de torify et du navigateur Tor (sans avoir besoin de Privoxy):
pip install PySocks
pip install pyTorify
(installez le navigateur Tor et démarrez-le)
Utilisation de la ligne de commande:
python -mtorify -p 127.0.0.1:9150 your_script.py
Ou intégré dans 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")
Remarque: le navigateur Tor utilise le port 9150 et non le 9050.
Tor est un proxy chaussettes. La connexion directe à celui-ci avec l'exemple cité échoue avec "erreur urlopen. La connexion au tunnel a échoué: 501 Tor n'est pas un proxy HTTP". Comme d'autres l'ont mentionné, vous pouvez résoudre ce problème avec Privoxy.
Alternativement, vous pouvez également utiliser PycURL ou SocksiPy. Pour des exemples d'utilisation des deux avec tor voir ...
https://stem.torproject.org/tutorials/to_russia_with_love.html