簡體   English   中英

Scrapy with Privoxy 和 Tor:如何更新 IP

[英]Scrapy with Privoxy and Tor: how to renew IP

我正在處理 Scrapy、Privoxy 和 Tor。 我已經全部安裝並正常工作。 但是 Tor 每次都連接同一個 IP,所以我很容易被禁止。 是否可以告訴 Tor 每 X 秒或連接重新連接一次?

謝謝!

編輯配置:對於用戶代理池,我這樣做了: http ://tangww.com/2013/06/UsingRandomAgent/(我不得不按照評論中的說明放置一個 _ init _.py 文件),以及對於 Privoxy 和 Tor,我遵循了http://www.andrewwatters.com/privoxy/ (我必須使用終端手動創建私有用戶和私有組)。 有效:)

我的蜘蛛是這樣的:

from scrapy.contrib.spiders import CrawlSpider
from scrapy.selector import Selector
from scrapy.http import Request

class YourCrawler(CrawlSpider):
    name = "spider_name"
    start_urls = [
    'https://example.com/listviews/titles.php',
    ]
    allowed_domains = ["example.com"]

    def parse(self, response):
        # go to the urls in the list
        s = Selector(response)
        page_list_urls = s.xpath('///*[@id="tab7"]/article/header/h2/a/@href').extract()
        for url in page_list_urls:
            yield Request(response.urljoin(url), callback=self.parse_following_urls, dont_filter=True)

        # Return back and go to bext page in div#paginat ul li.next a::attr(href) and begin again
        next_page = response.css('ul.pagin li.presente ~ li a::attr(href)').extract_first()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield Request(next_page, callback=self.parse)

    # For the urls in the list, go inside, and in div#main, take the div.ficha > div.caracteristicas > ul > li
    def parse_following_urls(self, response):
        #Parsing rules go here
        for each_book in response.css('main#main'):
            yield {
                'editor': each_book.css('header.datos1 > ul > li > h5 > a::text').extract(),
            }

在 settings.py 我有一個用戶代理旋轉和 privoxy:

DOWNLOADER_MIDDLEWARES = {
        #user agent
        'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware' : None,
        'spider_name.comm.rotate_useragent.RotateUserAgentMiddleware' :400,
        #privoxy
        'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
        'spider_name.middlewares.ProxyMiddleware': 100
    }

在 middlewares.py 我補充說:

class ProxyMiddleware(object):
    def process_request(self, request, spider):
        request.meta['proxy'] = 'http://127.0.0.1:8118'
        spider.log('Proxy : %s' % request.meta['proxy'])

我認為僅此而已……

編輯二---

好的,我更改了我的 middlewares.py 文件,正如博客@Tomáš Linhart 所說:

class ProxyMiddleware(object):
    def process_request(self, request, spider):
        request.meta['proxy'] = 'http://127.0.0.1:8118'
        spider.log('Proxy : %s' % request.meta['proxy'])

from stem import Signal
from stem.control import Controller

class ProxyMiddleware(object):
    def process_request(self, request, spider):
        request.meta['proxy'] = 'http://127.0.0.1:8118'
        spider.log('Proxy : %s' % request.meta['proxy'])

    def set_new_ip():
        with Controller.from_port(port=9051) as controller:
            controller.authenticate(password='tor_password')
            controller.signal(Signal.NEWNYM)

但是現在真的很慢,而且似乎沒有改變ip……我做對了還是有什么問題?

這篇文可能會對您有所幫助,因為它處理的是同一問題。

編輯:根據具體要求(每個請求或N個請求后的新 IP),在中間件的process_request方法中適當調用set_new_ip 但是請注意,對set_new_ip函數的調用不必始終確保新 IP(有一個指向 FAQ 的鏈接和解釋)。

EDIT2:帶有ProxyMiddleware類的模塊看起來像這樣:

from stem import Signal
from stem.control import Controller

def _set_new_ip():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='tor_password')
        controller.signal(Signal.NEWNYM)

class ProxyMiddleware(object):
    def process_request(self, request, spider):
        _set_new_ip()
        request.meta['proxy'] = 'http://127.0.0.1:8118'
        spider.log('Proxy : %s' % request.meta['proxy'])

但是 Tor 每次都連接同一個 IP

這是記錄在案的 Tor 功能

需要注意的重要一點是,新電路並不一定意味着新 IP 地址 路徑是根據速度和穩定性等啟發式方法隨機選擇的。 Tor 網絡中只有那么多大型出口,因此重復使用您之前擁有的出口並不少見。

這就是為什么使用下面的代碼會導致再次使用相同的 IP 地址的原因。

from stem import Signal
from stem.control import Controller


with Controller.from_port(port=9051) as controller:
    controller.authenticate(password='tor_password')
    controller.signal(Signal.NEWNYM)

https://github.com/DusanMadar/TorIpChanger可幫助您管理此行為。 免責聲明 - 我寫了TorIpChanger

我還整理了一份關於如何將 Python 與 Tor 和 Privoxy 結合使用的指南: https ://gist.github.com/DusanMadar/8d11026b7ce0bce6a67f7dd87b999f6b。


下面是一個示例,說明如何在“ProxyMiddleware”中使用“TorIpChanger”(“pip install toripchanger”)。
from toripchanger import TorIpChanger


# A Tor IP will be reused only after 10 different IPs were used.
ip_changer = TorIpChanger(reuse_threshold=10)


class ProxyMiddleware(object):
    _requests_count = 0

    def process_request(self, request, spider):
        self._requests_count += 1
        if self._requests_count > 10:
            self._requests_count = 0 
            ip_changer.get_new_ip()

        request.meta['proxy'] = 'http://127.0.0.1:8118'
        spider.log('Proxy : %s' % request.meta['proxy'])

或者,如果您想在 10 次請求后使用不同的 IP,您可以執行如下操作。

 from toripchanger import TorIpChanger # A Tor IP will be reused only after 10 different IPs were used. ip_changer = TorIpChanger(reuse_threshold=10) class ProxyMiddleware(object): _requests_count = 0 def process_request(self, request, spider): self._requests_count += 1 if self._requests_count > 10: self._requests_count = 0 ip_changer.get_new_ip() request.meta['proxy'] = 'http://127.0.0.1:8118' spider.log('Proxy: %s' % request.meta['proxy'])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM