Поиск по блогу

понедельник, 21 апреля 2014 г.

Два файла "Random proxy middleware for Scrapy "

В проекте Scrapy структура папок стандартизирована. В нее можно добавить всего два файла для ротации текстового прокси-листа с сайта hidemyass.com Внизу ссылки и копипаст кода с GitHub
Ранее я опробовал комбайн Pyproxy (управление из командной строки, сбор адресов с десятков сайтов со списками формата IP:Port), а здесь более простой вариант.

Первоисточники и ссылки

randomproxy.py

In []:
# Команда загружает вся страницу html, потому ниже ручной копипаст только работающего кода
%load 'https://github.com/aivarsk/scrapy-proxies/blob/master/randomproxy.py'
In []:
import re
import random
import base64
from scrapy import log

class RandomProxy(object):
    def __init__(self, settings):
        self.proxy_list = settings.get('PROXY_LIST')
        fin = open(self.proxy_list)

        self.proxies = {}
        for line in fin.readlines():
            parts = re.match('(\w+://)(\w+:\w+@)?(.+)', line)

            # Cut trailing @
            if parts[1]:
                parts[1] = parts[1][:-1]

            self.proxies[parts[0] + parts[2]] = parts[1]

        fin.close()

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler.settings)

    def process_request(self, request, spider):
        # Don't overwrite with a random one (server-side state for IP)
        if 'proxy' in request.meta:
            return

        proxy_address = random.choice(self.proxies.keys())
        proxy_user_pass = self.proxies[proxy_address]

        request.meta['proxy'] = proxy_address
        if proxy_user_pass:
            basic_auth = 'Basic ' + base64.encodestring(proxy_user_pass)
            request.headers['Proxy-Authorization'] = basic_auth

    def process_exception(self, request, exception, spider):
        proxy = request.meta['proxy']
        log.msg('Removing failed proxy <%s>, %d proxies left' % (
                    proxy, len(self.proxies)))
        try:
            del self.proxies[proxy]
        except ValueError:
            pass

settings.py

In []:
# Retry many times since proxies often fail
RETRY_TIMES = 10
# Retry on most error codes since proxies fail for different reasons
RETRY_HTTP_CODES = [500, 503, 504, 400, 403, 404, 408]

DOWNLOADER_MIDDLEWARES = {
    'scrapy.contrib.downloadermiddleware.retry.RetryMiddleware': 90,
    # Fix path to this module
    'yourspider.randomproxy.RandomProxy': 100,
    'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 110,
}

# Proxy list containing entries like
# http://host1:port
# http://username:password@host2:port
# http://host3:port
# ...
PROXY_LIST = '/path/to/proxy/list.txt'

Your spider

In each callback ensure that proxy /really/ returned your target page by checking for site logo or some other significant element. If not - retry request with dont_filter=True
In []:
if not hxs.select('//get/site/logo'):
    yield Request(url=response.url, dont_filter=True)


Посты чуть ниже также могут вас заинтересовать

Комментариев нет:

Отправить комментарий