Comment implémenter différent IP pour différents comptes de login avec un spider avec Scrapy?
J'ai beaucoup de pages à scraper, environ 200 000. D'habitude j'utilise Tor et Polipo proxy pour cacher le comportement de mes spiders même si ils sont polis, on ne sait jamais. Le problème c'est qu'en utilisant un compte pour se connecter à la page web, qui contient des informations intéressantes seulement si on se connecte, avoir une adresse IP changeante ce n'est pas très utile puisqu'il suffit au serveur de bannir le compte. En soi je sais comment faire tourner différentes "versions" d'un même spider:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class ASpider(scrapy.Spider):
name = "spider"
start_urls = ['https://www.a_website.com/compte/login']
def __init__ (self, username=None, password=None):
self.username = username
self.password = password
def parse(self, response):
token = response.css('[name="_csrf_token"]::attr(value)').get()
data_log = {
'_csrf_token': token,
'_username': self.username,
'_password': self.password
}
yield scrapy.FormRequest.from_response(response, formdata=data_log, callback=self.after_login) #La suite n'importe pas |
Ainsi il suffit de lancer plusieurs commandes:
Code:
1 2
| scrapy crawl spider -a username=Bidule -a password=TMTC #cmd1
scrapy crawl spider -a username=Truc -a password=TMTC #cmd2 |
Donc lancer un scrap avec plusieurs comptes en même temps pour aller plus vite et ne pas trop éveiller les soupçons du serveur je sais faire par contre de là à implémenter une adresse IP à chacun de ces spiders lancés, je ne sais pas faire. Peut-être que cela se fait déjà de toute façon avec la suite du code que je vais vous montrer, mais je ne sais pas comment le vérifier, et si il s'avérait que les différents spiders partagent le même IP je ne saurais pas comment faire autrement à l'heure actuelle.
Pour plus de détails j'utilise ceci dans middlewares.py:
Code:
1 2 3 4
| class ProxyMiddleware(object):
def process_request(self, request, spider):
request.meta['proxy'] = settings.get('HTTP_PROXY') |
et ceci dans settings.py:
Code:
1 2 3 4 5 6 7
| # proxy for polipo
HTTP_PROXY = 'http://127.0.0.1:8123'
....
DOWNLOADER_MIDDLEWARES = {
'folder.middlewares.RandomUserAgentMiddleware': 400,
'folder.middlewares.ProxyMiddleware': 410, #Ici pour proxy
'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None} |
Ce sont des schémas que j'ai copié depuis des exemples de tutos, mais je ne maîtrise pas la compétence pour autant.
Essai de bindaddress Echec
J'ai mis ce que l'on trouve dans ce topic
Dans middlewares.py:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class BindAddressMiddleware(object):
def __init__(self, settings):
self.is_bindaddress = settings.get('IS_MORE_NETWORK_CARDS')
if self.is_bindaddress:
self.bindaddress = settings.get('BIND_ADDRESS')
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.settings)
def process_request(self, request, spider):
if self.is_bindaddress:
if self.bindaddress:
request.meta['bindaddress'] = (self.bindaddress, 0)
return None
def spider_opened(self, spider):
spider.logger.info('Using: %s as bindaddress' % self.bindaddress) |
settings.py
Code:
1 2 3 4 5 6 7 8 9
| IS_MORE_NETWORK_CARDS = True
BIND_ADDRESS = "127.0.0.1"
...
DOWNLOADER_MIDDLEWARES = {
'folder.middlewares.RandomUserAgentMiddleware': 400,
'folder.middlewares.ProxyMiddleware': 410,
'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,
'folder.middlewares.BindAddressMiddleware': 400,
} |
J'ai toujours les mêmes adresses IP en lançant mes commandes comme montré plus haut. S'agit-il d'un petit règlagle dans les settings.py et middlewares.py? Ou bien qqch de plus conséquent?
On notera que les protocoles internet ne sont pas mon domaine, je sais comment marche un proxy de façon générale (intermédiaire qui permet de cacher l'IP du réel envoyeur et receveur dans mon cas) mais dans le détail non.