Как вернуть браузер selenium (или как импортировать def, который возвращает браузер selenium)

Я хотел бы запустить браузер selenium с конкретной настройкой (privoxy, Tor, randon user agent...) в функции, а затем вызвать эту функцию в моем коде. Я создал python script mybrowser.py с этим внутри:

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from fake_useragent import UserAgent
from stem import Signal
from stem.control import Controller

class MyBrowserClass:
    def start_browser():
        service_args = [
            '--proxy=127.0.0.1:8118',
            '--proxy-type= http',
            ]
        dcap = dict(DesiredCapabilities.PHANTOMJS)
        dcap["phantomjs.page.settings.userAgent"] = (UserAgent().random)

        browser = webdriver.PhantomJS(service_args = service_args,         desired_capabilities=dcap)
        return browser

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

Затем я импортирую его в другой script myscraping.py с помощью этого внутри:

import mybrowser
import time

browser= mybrowser.MyBrowserClass.start_browser()
browser.get("https://canihazip.com/s")
print(browser.page_source)
mybrowser.MyBrowserClass.set_new_ip()
time.sleep(12) 
browser.get("https://canihazip.com/s")
print(browser.page_source)

Браузер работает - я могу получить доступ к странице и получить ее с помощью .page_source.

Но IP-адрес не изменяется между первым и вторым отпечатками. Если я перемещаю содержимое функции внутри myscraping.py (и удаляю вызов функции "импорт + функция" ), то IP-изменение.

Почему? Это проблема с возвратом браузера? Как я могу это исправить?


На самом деле ситуация немного сложнее. Когда я подключаюсь к https://check.torproject.org до и после вызова mybrowser.set_new_ip() и wait of 12 sec (см. Строки ниже), IP-адрес, заданный веб-страницей, изменяется между первым и вторым вызовами. Таким образом, мой Ip изменяется (acroding to Tor), но ни https://httpbin.org/ip, ни icanhazip.com не обнаруживают изменения в IP.

...
browser.get("https://canihazip.com/s")
print(browser.page_source)
browser.get("https://check.torproject.org/")
print(browser.find_element_by_xpath('//div[@class="content"]').text )
mybrowser.set_new_ip()
time.sleep(12) 
browser.get("https://check.torproject.org/")
print(browser.find_element_by_xpath('//div[@class="content"]').text )
browser.get("https://canihazip.com/s")
print(browser.page_source)

Итак, напечатанные IP-адреса таковы:

42.38.215.198 (canihazip before mybrowser.set_new_ip() )
42.38.215.198  (check.torproject before mybrowser.set_new_ip() )
106.184.130.30  (check.torproject after mybrowser.set_new_ip() )
42.38.215.198 (canihazip after  mybrowser.set_new_ip())

Конфигурация Privoxy: в C:\Program Files (x86)\Privoxy\config.txt, я раскоментировал эту строку (9050 - это использование порта Tor):

forward-socks5t   /               127.0.0.1:9050 

Конфигурация Tor: в torcc у меня есть это

ControlPort 9051
HashedControlPassword : xxxx

Ответ 1

Controller изменяется каждый раз при вызове set_new_ip.

В принципе, Controller.from_port возвращает объект Controller, который наследует объект ControlSocket, который по очереди реализует методы контекстного менеджера __enter__ и __exit__.

Вам нужно убедиться, что вы используете тот же контекст для объекта Controller, что и для объекта browser.

Самый простой способ добиться этого, на мой взгляд, - создать Class, который реализует методы start_browser и set_new_ip, а сам класс после его создания будет содержать только экземпляр для браузера и, соответственно, для контроллера.

Пример:

class MyBrowserClass:
    service_args = [
        '--proxy=127.0.0.1:8118',
        '--proxy-type= http',
        ]
    dcap = dict(DesiredCapabilities.PHANTOMJS)
    dcap["phantomjs.page.settings.userAgent"] = (UserAgent().random)

    def __init__(self):
        self.browser = webdriver.PhantomJS(service_args = self.service_args,         desired_capabilities=self.dcap)
        self.controller = Controller.from_port(port=9051)

    def set_new_ip():
        self.controller.authenticate(password=password) 
        self.controller.signal(Signal.NEWNYM)


browserClassInstance = MyBrowserClass() # at this point the browser is started
browserClassInstance.browser.get("https://canihazip.com/s")
browserClassInstance.set_new_ip() # works with the SAME controller any time called. Doesn't create a new controller each time