[英]How to use Scrapy with both Splash and Tor over Privoxy in Docker Compose
[英]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。
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.