Как вернуть браузер 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