16
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ScrapyでProxyを使う方法

Last updated at Posted at 2018-03-30

Proxyの使い方

Proxyの機能は HttpProxyMiddleware で提供されていて、デフォルトで利用可能となっている。
Requestオブジェクトに対しmetaキーで指定することで利用できる。

公式ドキュメントはこちら。

# e.g.
url = 'http://example.com/'
meta = {'proxy': 'http://145.239.92.106:3128'}
scrapy.Request(url, meta=meta)

SpiderのRequestでProxyを使う

start_urls に指定したURLへのアクセスにProxyを使うには start_requests() をOverrideすればよい。start_requests()のドキュメントはこちら

class MySpider(scrapy.Spider):
    start_requests = ['http://www.example1.com/', 'http://www.example2.com/']

    def start_requests(self):
        for url in self.start_urls:
            meta = {'proxy': 'http://145.239.92.106:3128'}
            yield scrapy.Request(url, meta=meta)

CrawlSpiderのRequestでProxyを使う

start_requests() のOverrideはSpiderと同様にする必要がある。
しかしCrawlSpiderの場合はRuleによって得られたLinkへアクセスするRequestにもProxyを設定する必要がある。

この場合 _build_request() をOverrideすればよい。 CrawlSpiderのソースコードはこちら

class MySpider(CrawlSpider):
    def _build_request(self, rule, link):
        # CrawlSpider の実装
        #r = Request(url=link.url, callback=self._response_downloaded)
        #r.meta.update(rule=rule, link_text=link.text)
        #return r
        r = super(MySpider, self)._build_request(rule, link)
        r.meta.update(proxy='http://175.139.252.193:80')
        return r

複数のProxyを設定して利用する

Proxyを複数用意してランダムで利用する。Proxyは外部ファイルで設定しておくと利用しやすい。

proxies.yml
---
- http://190.145.80.114:3130
- http://148.217.94.54:3128
- http://125.212.207.121:3128
class MySpider(scrapy.Spider):
    proxies = None

    # proxies.yml からランダムに選ぶ
    def get_proxy(self):
        if not self.proxies:
            f = open('proxies.yml')
            self.proxies = yaml.load(f)
            f.close()
        return self.proxies[int(random() * len(self.proxies))]

    def start_requests(self):
        for url in self.start_urls:
            meta = {'proxy': self.get_proxy()}
            yield scrapy.Request(url, meta=meta)    

Proxyのエラーに対処する

Proxyが動いていなかったり、アクセスが拒否された時には別のProxyを設定したい。こういう場合には errback にcallbackメソッドを指定する。

class MySpider(scrapy.Spider):
    start_requests = ['http://www.example1.com/', 'http://www.example2.com/']
    proxies = None

    def get_proxy(self):
        if not self.proxies:
            f = open('proxies.yml')
            self.proxies = yaml.load(f)
            f.close()
        return self.proxies[int(random() * len(self.proxies))]

    def start_requests(self):
        for url in self.start_urls:
            meta = {'proxy': self.get_proxy()}
            yield scrapy.Request(
                url,
                meta=meta,
                callback=self.parse_page,
                errback=self.new_request
            )

    def new_request(self, failure):
        meta = {'proxy': self.get_proxy()}
        yield scrapy.Request(
            url=failure.request.url,
            meta=meta,
            callback=self.parse_page,
            errback=self.new_request
        )

Tips 利用可能なProxyのリストを作る

ワンライナーでproxyをチェックする

フリーのプロキシーサーバーはこういったサイトにまとめられている。必要に応じてピックアップし一覧にする。
例えばこのようなもの。

$ cat proxy_list
192.241.157.239:8080
125.212.207.121:3128
145.239.92.106:3128
185.93.3.123:8080
175.139.252.193:80

簡単なワンライナーでチェックして利用の可否を判定する。

$ cat proxy_list |\
  xargs -I@ bash -c "URL=@; curl --proxy http://@ http://example.com 1>/dev/null 2>&1 && echo success \$URL || echo failure \$URL"

success となったProxyを利用する。

16
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?