Signal.NEWNYM не дает новый IP-адрес при использовании в промежуточном программном обеспечении scrapy - PullRequest
1 голос
/ 29 марта 2020

Я использую сканер веб-поиска с privoxy и tor. Все правильно настроено, и я могу просматривать сеть через privoxy.

Я хочу, чтобы ip, используемый для очистки каждого адреса, менялся с каждым запросом / x числом запросов. Я использую controller.signal(Signal.NEWNYM) с промежуточным ПО для прокси, чтобы попытаться выполнить следующий ответ: Scrapy с Privoxy и Tor: как обновить IP , но я не получаю никаких изменений ip.

Это промежуточное программное обеспечение, используемое для изменения цепей tor и ip:

def _set_new_ip():
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='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, однако я протестировал controller.signal(Signal.NEWNYM) в отдельный скрипт и обнаружил, что смена цепей tor действительно приводит к изменению periodi c в ip. Вот сценарий, который я использовал для тестирования:

def set_new_ip():
    """Change IP using TOR"""
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='password')
        controller.signal(Signal.NEWNYM)

while True:

    set_new_ip()

    local_proxy = '127.0.0.1:8118'
    http_proxy = {
        'http': local_proxy,
        'https': local_proxy
    }

    current_ip = requests.get(
        url='http://icanhazip.com/',
        proxies=http_proxy,
        verify=False
    )

    print(current_ip.content)

Из этого сценария я получу вывод, подобный следующему, показывающий изменение periodi c ip:

09.70.100.27\n'
b'109.70.100.27\n'
b'109.70.100.27\n'
b'109.70.100.27\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'198.98.58.135\n'
b'185.220.101.2\n'
b'185.220.101.2\n'
b'185.220.101.2\n'
b'185.220.101.2\n'
b'185.220.101.2\n'
b'185.220.101.2\n'
b'185.220.101.2\n'

Еще с моим паук Я не получаю эту периодику c изменения. В ip-log.csv я просто получаю гигантский список одного и того же IP-адреса, повторяемый снова и снова. Что я делаю не так?

Это код паука, который я использую:

class Spider(scrapy.Spider):

   name = 'spider'
   dir = '/a/path'
   with open(dir + 'results.csv', 'w', newline='') #open .csv file to record results from scraping

   with open(dir + 'ip-log.csv', 'w', newline='') #open .csv file to record ip used for each request

   def start_requests(self):

      url = 'https://url.com'
      yield scrapy.request(url, callback=self.parse)


   #collect listed urls
   def parse(self, response):

       path = '/response/xpath/@href'
       if response.xpath(path):

           for href in response.xpath(path).extract():

               yield Request(url=response.urljoin(href), callback=self.save_result)

               url = response.request.url.split('&')
               for item in url:

                   if item.startswith('index='):
                       page_index = item.split('=')[-1]

               next_page = ['index=' + str(int(page_index) + 24) if x.startswith('index=') else x for x in url]
               next_page = '&'.join(next_page)
               yield scrapy.Request(url=next_page, callback=self.parse)

               #use icanhazip.com to get ip used for request
               yield scrapy.Request('https://icanhazip.com', callback=self.check_ip, dont_filter=True)   

   #record ip
   def check_ip(self, response):

      ip = response.xpath('/html/body/p').extract()
      dir = '/a/path'

         with open(dir + '/ip-log.csv', 'a+', newline='') as f:   #write request ip in .csv file

            writer = csv.writer(f)
            writer.writerow([ip])

      yield scrapy.Request('https://icanhazip.com', callback=self.parse, dont_filter=True)

    #visit each url and save results
    def save_result(self, response):

       dir = '/a/path'

       path = '/desired/xpath'
       result = response.xpath(path).extract()

       with open(dir + '/results.csv', 'a+', newline='') as f:

           writer = csv.writer(f)
           writer.writerow([price])   #save results to results.csv

1 Ответ

0 голосов
/ 31 марта 2020

Очевидно, что tor не хочет переключать IP при посещении icanhazip.com. Я попробовал тот же код на другом сайте ('http://whatsmyuseragent.org/'), и теперь ip периодически меняется. Протестировано это с отключенным соответствующим промежуточным программным обеспечением (http://whatsmyuseragent.org/ показывал тот же невидимый ip без изменения periodi c).

...