How to return selenium browser(或如何导入 def that return selenium browser)
How to return selenium browser (or how to import a def that return selenium browser)
我想在一个函数中启动一个带有特定设置(privoxy、Tor、randon 用户代理...)的 selenium 浏览器,然后在我的代码中调用这个函数。我在里面创建了一个 python 脚本 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)
然后我将它导入到另一个脚本 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 会发生变化。
为什么?是不是退回浏览器的问题?我该如何解决这个问题?
实际上,情况要复杂一些。当我在调用 mybrowser.set_new_ip()
和 wait of 12 sec
之前和之后连接到 https://check.torproject.org
时(参见下面的行),网页给出的 IP 在第一次和第二次调用之间发生变化。所以我的 IP 已更改(根据 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
这 可能 因为 PhantomJS 保留请求内容的 内存缓存 。因此,您使用 PhantomJS 浏览器的第一次访问可能会产生动态结果,但该结果随后会被缓存,每次连续访问都会使用该缓存页面。
这个 内存缓存 导致了 CSRF-Token
在刷新时没有改变等问题,现在我相信这是问题的根本原因。 issue 于 2013 年提出并解决,但解决方案是一种方法,clearMemoryCache
,可在 PhantomJS 的 WebPage
class 中找到。可悲的是,我们正在处理一个 Selenium webdriver.PhantomJS
实例。
因此,除非我在监督某些事情,否则很难通过 Selenium 的抽象访问此方法。
我认为唯一合适的解决方案是使用另一个没有像 PhantomJS 那样的 内存缓存 的网络驱动程序。我已经使用 Chrome 对其进行了测试,并且效果很好:
103.***.**.***
72.***.***.***
此外,作为旁注,Selenium 正在逐步淘汰 PhantomJS:
UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead
您可能需要检查是否有可用的新 nym。
is_newnym_available - 如果 tor 当前接受 NEWNYM 信号则为真
if controller.is_newnym_available():
controller.signal(Signal.NEWNYM)
我想在一个函数中启动一个带有特定设置(privoxy、Tor、randon 用户代理...)的 selenium 浏览器,然后在我的代码中调用这个函数。我在里面创建了一个 python 脚本 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)
然后我将它导入到另一个脚本 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 会发生变化。
为什么?是不是退回浏览器的问题?我该如何解决这个问题?
实际上,情况要复杂一些。当我在调用 mybrowser.set_new_ip()
和 wait of 12 sec
之前和之后连接到 https://check.torproject.org
时(参见下面的行),网页给出的 IP 在第一次和第二次调用之间发生变化。所以我的 IP 已更改(根据 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
这 可能 因为 PhantomJS 保留请求内容的 内存缓存 。因此,您使用 PhantomJS 浏览器的第一次访问可能会产生动态结果,但该结果随后会被缓存,每次连续访问都会使用该缓存页面。
这个 内存缓存 导致了 CSRF-Token
在刷新时没有改变等问题,现在我相信这是问题的根本原因。 issue 于 2013 年提出并解决,但解决方案是一种方法,clearMemoryCache
,可在 PhantomJS 的 WebPage
class 中找到。可悲的是,我们正在处理一个 Selenium webdriver.PhantomJS
实例。
因此,除非我在监督某些事情,否则很难通过 Selenium 的抽象访问此方法。
我认为唯一合适的解决方案是使用另一个没有像 PhantomJS 那样的 内存缓存 的网络驱动程序。我已经使用 Chrome 对其进行了测试,并且效果很好:
103.***.**.***
72.***.***.***
此外,作为旁注,Selenium 正在逐步淘汰 PhantomJS:
UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead
您可能需要检查是否有可用的新 nym。
is_newnym_available - 如果 tor 当前接受 NEWNYM 信号则为真
if controller.is_newnym_available():
controller.signal(Signal.NEWNYM)